2016-01-12 1 views
-1

J'essaie d'utiliser des classes imbriquées à la place de l'héritage multiple. Je suis les recommandations du livre mais je continue à obtenir une erreur dans le constructeur. Fondamentalement, la personne est le grand-père, l'étudiant et l'employé sont les parents et l'assistant d'enseignement est l'enfant. TeachingAssistant aura une classe imbriquée qui aura référence à sa classe externe, mais quand j'utilise le code du livre que j'obtenir deux erreursUtilisation de classes imbriquées au lieu d'héritage multiple, C++

Je reçois l'erreur

Erreur 1 * "Aucun constructeur correspondant pour l'initialisation de TeachingAssistant :: EmployeePart »

et cette erreur

erreur 2 "hors de la définition de la ligne de 'EmployeePart' ne correspond à aucune déclaration 'TeachingAssistant :: EmployeePart'"

Voici le code:

class TeachingAssistant : public Student 
{ 
public: 
    TeachingAssistant(); 
private: 
    class EmployeePart; 
    EmployeePart* employee_ptr; 
}; 

class TeachingAssistant::EmployeePart : public Employee 
{ 
public: 
    EmployeePart(TeachingAssistant&); 
private: 
    TeachingAssistant* ta_part; // Allows access back to outer class 
}; 

Erreur 1 est ici dans ce constructeur

TeachingAssistant::TeachingAssistant() 
{ 
    employee_ptr = new EmployeePart(this); // Pass pointer to implicit parameter 
} 

Erreur 2 est ici

TeachingAssistant::EmployeePart::EmployeePart(TeachingAssistant* taval) 
: ta_part(taval) {} 

Pourquoi ces erreurs pop-up si je fournirai la constructeurs?

+1

'(* TeachingAssistant Taval)' est pas la même signature que dans la déclaration 'EmployeePart (TeachingAssistant &);'. –

+0

Avez-vous essayé de définir la construction par défaut 'EmployeePart()' pour corriger l'erreur 1? – Artwo

+0

Je reçois toujours l'erreur si j'utilise le constructeur par défaut – user2076774

Répondre

1

Votre de base est que vous avez appelé le constructeur EmployeePart à tort et défini à tort. Cependant, pendant que nous corrigeons cela, nous aborderons également le fait que vous préférez ne pas utiliser new, et ne pas utiliser de pointeurs bruts possédant de la mémoire, et ne pas utiliser de pointeurs lorsque vous n'avez pas besoin de nullabilité ou de ré-applicabilité.

class TeachingAssistant : public Student 
{ 
public: 
    TeachingAssistant(); 
    TeachingAssistant(const TeachingAssistant&rhs) = delete; // Delete copy constructor. 
    TeachingAssistant& operator=(const TeachingAssistant&rhs) = delete; // And assignment. 
private: 
    class EmployeePart; 
    std::unique_ptr<EmployeePart> employee_ptr; // First change here. 
}; 

class TeachingAssistant::EmployeePart : public Employee 
{ 
public: 
    EmployeePart(TeachingAssistant&);  
private: 
           // Second change here. Store reference, not pointer. 
    TeachingAssistant& ta_part; // Allows access back to outer class 
}; 

Créer la employee_ptr dans la liste d'initialisation, et passer *this, pas this.

TeachingAssistant::TeachingAssistant() 
    : employee_ptr(std::make_unique<EmployeePart>(*this)) // Pass reference to constructor 
{ 
} 

changement quatrième est sur la ligne suivante:

TeachingAssistant::EmployeePart::EmployeePart(TeachingAssistant& taval) 
: ta_part(taval) {} 
+0

Pourquoi ne pas utiliser des pointeurs bruts? – user2076774

+0

Si vous utilisez un pointeur brut pour 'employee_ptr', vous devez vous soucier d'un destructeur (pour libérer la mémoire) et copier les constructeurs (vous ne voulez pas que les pointeurs pointent sur le même bloc, si leurs destructeurs vont tous les deux le libérer), et de même pour l'attribution de copie. Si vous utilisez unique_ptr, destructor et déplacez constructor/assigment "just work" et que copy constructor/assignment ne compilera pas jusqu'à ce que vous écriviez une spécialisation. –

+0

L'utilisation d'un pointeur pour 'ta_part' est moins problématique, mais étant donné que vous ne voulez jamais pouvoir changer l'adresse du TA qui possède cette partie employee, et que vous ne voulez jamais qu'elle soit nulle, une référence correspond mieux à la sémantique. –

0
EmployeePart(TeachingAssistant&); 

Votre constructeur veut référence, mais vous passez this avec pointeur est employee_ptr = new EmployeePart(this); passe * ce lieu

Deuxième erreur. Votre déclaration est différente de la définition. Voir problème TeachingAssistant* taval et EmployeePart(TeachingAssistant&);