2016-01-12 4 views
-1

Я пытаюсь использовать вложенные классы вместо множественного наследования. Я следую рекомендациям из книги, но я продолжаю получать ошибку в конструкторе. В принципе, человек - дедушка, ученик и служащий - родитель, а помощник по обучению - ребенок. TeachingAssistant будет иметь вложенный класс, который будет иметь ссылку на его внешний класс, но когда я использую код из книги я получаю две ошибкуИспользование вложенных классов вместо множественного наследования, C++

Я получаю ошибку

Ошибки 1 * "Нет соответствие конструктора для инициализации TeachingAssistant :: EmployeePart»

и эта ошибка

ошибка 2 "из определения линии 'EmployeePart' не соответствует ни одной декларации в 'TeachingAssistant :: EmployeePart"

Вот код:

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 
}; 

Ошибка 1 находится здесь, в этом конструкторе

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

Ошибка 2 здесь

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

Почему эти ошибки выскакивают, если я ОКАЗЫВАЛОСЬ конструкторы?

+1

'(TeachingAssistant * taval)' не то же самое, как подписи в декларации 'EmployeePart (TeachingAssistant &);'. –

+0

Вы пытались определить конструкцию по умолчанию 'EmployeePart()' для исправления ошибки 1? – Artwo

+0

Я до сих пор получаю сообщение об ошибке, если я использую конструктор по умолчанию – user2076774

ответ

1

Вашей основной проблема заключается в том, что вы назвали конструктор EmployeePart неправильно, и определили его неправильно. Однако, хотя мы исправим это, мы также рассмотрим тот факт, что вы не должны использовать new, а не использовать необработанные указатели, в которых есть собственная память, а не использовать указатели, когда вам не нужна нулеустойчивость или нерегулярность.

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 
}; 

Создать employee_ptr в списке инициализации, и передать *this, не this.

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

Четвертое изменение на следующей строке:

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

Почему вы не должны использовать необработанные указатели? – user2076774

+0

Если вы используете raw-указатель для 'employee_ptr', вам нужно беспокоиться о деструкторе (освободить память) и скопировать конструкторы (вы не хотите, чтобы указатели указывали на один и тот же блок, если их деструкторы оба собираются бесплатно), а также для копирования. Если вы используете unique_ptr, деструктор и переместите конструктор/ассистент «просто работайте», а конструктор/назначение копии не будут компилироваться, пока вы не напишете специализацию. –

+0

Использование указателя для 'ta_part' менее проблематично, но, учитывая, что вы никогда не захотите изменить адрес TA, которому принадлежит эта employee_part, и вы никогда не хотите, чтобы он был нулевым, ссылка лучше соответствует семантике. –

0
EmployeePart(TeachingAssistant&); 

Ваш конструктор хочет ссылку, но вы передаете this с указателем является employee_ptr = new EmployeePart(this); проход * это вместо

Вторая ошибка. Ваше заявление отличается от определения. См TeachingAssistant* taval и EmployeePart(TeachingAssistant&);

Смежные вопросы