Problema em chamar construtor de classe base na herança

1. Problema em chamar construtor de classe base na herança

Igor Alvim
AlvimIgor

(usa Ubuntu)

Enviado em 10/09/2017 - 02:34h

Pessoal, estou pagando estruturas de dados na faculdade em C++ e essa linguagem é muito louca >.<
Estou tentando chamar o construtor da classe mãe no construtor das classes herdeiras, mas aparece o seguinte erro:
error: no matching function for call to ‘Veiculo::Veiculo(std::__cxx11::string&)’


Aí vai o código:
veiculo.h

#ifndef VEICULO_H_
#define VEICULO_H_
#include <iostream>
using namespace std;

class Veiculo {

protected:
	string nome;

public:

	Veiculo(const char *nome) {
		this->nome = string(nome);
		cout << "Criação de Veículo" << nome << endl;
	}

	~Veiculo(){
		cout << "Destruição de Veículo" << nome << endl;
	}

};

class Terrestre : public Veiculo {
public:

	Terrestre() : Veiculo(nome){
		this->nome = Veiculo::nome;
		cout << "Criação de Terrestre" << nome << endl;
	};

	~Terrestre() : Veiculo() {
		cout << "Destruição de Terrestre" << nome << endl;
	}
};

class Aquatico : public Veiculo {
public:

	Aquatico() : Veiculo(nome) {
		this->nome = Veiculo::nome;
		cout << "Criação de Aquatico" << nome << endl;
	};

	~Aquatico() {
		cout << "Destruição de Aquatico" << nome << endl;
	}

};

class Aereo : public Veiculo {
public:

	Aereo() : Veiculo(nome) {
		this->nome = Veiculo::nome;
		cout << "Criação de Aereo" << nome << endl;

	};

	~Aereo() {
		cout << "Destruição de Aereo" << nome << endl;
	}

};


#endif /* VEICULO_H_ */
 


principal.cpp:
#include <iostream>
#include "veiculo.h"

using namespace std;

int main() {
	cout << "Segunda pratica de AED em C++" << endl;

	Veiculo v1("v1");
	Terrestre t1("t1");
	Aquatico aq1("aq1");
	Aereo ar1("ar1");
}
 



  


2. Re: Problema em chamar construtor de classe base na herança

Fernando
phoemur

(usa Debian)

Enviado em 10/09/2017 - 20:17h

Seu veículo aceita const char* (string literal), porém você está chamando com std::string...
Essa conversão implícita não funciona sempre em duas vias...

dito issso:

const char* == std::string().c_str()
std::string == std::string(const char*)

Para funcionar, sugiro trocar tudo por std::string que é mais difícil dar tiro no pé.
Consertei alguns erros de digitação tb.

#ifndef VEICULO_H_
#define VEICULO_H_

#include <iostream>
#include <string>
using namespace std;

class Veiculo {
protected:
        string nome;

public:
        Veiculo(const string& arg) 
            : nome{arg}
        {
                cout << "Criação de Veículo " << nome << endl;
        }

        ~Veiculo()
        {
                cout << "Destruição de Veículo " << nome << endl;
        }
};

class Terrestre : public Veiculo {
public:
        Terrestre(const string& arg)
            : Veiculo(arg)
        {
                cout << "Criação de Terrestre " << nome << endl;
        }

        ~Terrestre()
        {
                cout << "Destruição de Terrestre " << nome << endl;
        }
};

class Aquatico : public Veiculo {
public:
        Aquatico(const string& arg)
            : Veiculo(arg)
        {
                cout << "Criação de Aquatico " << nome << endl;
        }

        ~Aquatico()
        {
                cout << "Destruição de Aquatico " << nome << endl;
        }
};

class Aereo : public Veiculo {
public:
        Aereo(const string& arg)
            : Veiculo(arg)
        {
                cout << "Criação de Aereo " << nome << endl;
        }

        ~Aereo()
        {
                cout << "Destruição de Aereo " << nome << endl;
        }
};

#endif /* VEICULO_H_ */
 


Se o construtor da classe base não aceitasse nenhum argumento (default constructor), o c++ chamaria ele sozinho pra você, porém como você precisa chamar com o nome (uma std::string), você precisa chamar explicitamente assim como no meu exemplo.

Outra coisa a se lembrar é que não é boa prática de programação colocar
 using namespace std;  

em um header file, pois pode "contaminar" o namespace global... Deixa o cliente decidir como quer fazer.

Outra coisa é que como você definiu um destructor, o compilador não vai mais gerar automaticamente os construtores que geralmente faz (copy constructor, copy assignment, move constructor, move assignment, destructor).
Se você definir algum desses recomenda-se que defina todos os outros, nem que seja um =default;
Mas isso é mais pra frente, a depender do comportamento que você quer pra sua classe.

Outra coisa é que o this->nome é desnecessário pois a classe já herdou o nome e é só usar direto.








Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts