Очень базовое наследование: ошибка: ожидаемое имя класса до '{токена
Я пытаюсь узнать c++, и я наткнулся на ошибку, пытаясь понять наследство.
Компиляция: дочерний.cpp В файле, включенном в /home/jonas/kodning/testing/daughter.cpp:1: /home/jonas/kodning/testing/daughter.h:6: ошибка: ожидаемое имя класса до '{токен процесса завершено со статусом 1 (0 минут, 0 секунд) 1 ошибка, 0 предупреждений
Мои файлы: main.cpp:
#include "mother.h"
#include "daughter.h"
#include <iostream>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
mother mom;
mom.saywhat();
return 0;
}
mother.cpp:
#include "mother.h"
#include "daughter.h"
#include <iostream>
using namespace std;
mother::mother()
{
//ctor
}
void mother::saywhat() {
cout << "WHAAAAAAT" << endl;
}
mother.h:
#ifndef MOTHER_H
#define MOTHER_H
class mother
{
public:
mother();
void saywhat();
protected:
private:
};
#endif // MOTHER_H
daughter.h:
#ifndef DAUGHTER_H
#define DAUGHTER_H
class daughter: public mother
{
public:
daughter();
protected:
private:
};
#endif // DAUGHTER_H
и дочь.cpp:
#include "daughter.h"
#include "mother.h"
#include <iostream>
using namespace std;
daughter::daughter()
{
//ctor
}
То, что я хочу сделать, - позволить дочери наследовать все, что угодно, от материнского класса (= saywhat()). Что я делаю не так?
Ответы
Ответ 1
Вы забыли включить mother.h
здесь:
#ifndef DAUGHTER_H
#define DAUGHTER_H
#include "mother.h" //<--- this line is added by me.
class daughter: public mother
{
public:
daughter();
protected:
private:
};
#endif // DAUGHTER_H
Вы должны включить этот заголовок, потому что daughter
получена от mother
. Поэтому компилятор должен знать определение mother
.
Ответ 2
Во-первых, у вас есть защитники в файлах реализации. Удалить их.
Во-вторых, если вы наследуете от класса, вам нужно включить заголовок, где определяется класс.
Ответ 3
В child.cpp переключите две строки include. т.е.
#include "mother.h"
#include "daughter.h"
Случилось так, что компилятор изучает определение daughter
класса и не может найти определение mother
базы базового класса. Поэтому он говорит вам, что "я ожидаю, что идентификатор" mother
перед" {"в строке
class daughter: public mother {
быть классом, но я не могу найти его определения! "
В mother.cpp
удалите включение daughter.h
элемента. Компилятору не нужно знать определение daughter.h
; т.е. mother
класса может использоваться без daughter
. Добавление включения daughter.h
вводит ненужную зависимость между определениями классов.
С другой стороны, всегда лучше, чтобы IMHO сохранял включение заголовка в определение класса (.cpp), а не объявление класса (.h). Таким образом, менее вероятно, что вам нужно разрешить кошмар включения заголовка при включении заголовков, которые, в свою очередь, включают другие заголовки, которые у вас отсутствуют. Но многие производственные коды включают заголовок в заголовке. Оба правильные, просто нужно быть осторожными, когда вы это делаете.
Ответ 4
Убедитесь, что #ifndef
и #define
в вашем заголовочном файле уникальны.
#ifndef BASE_CLIENT_HANDLER_H
#define BASE_CLIENT_HANDLER_H
#include "Threads/Thread.h"
class BaseClientHandler : public threads::Thread {
public:
bool isOn();
};
#endif //BASE_CLIENT_HANDLER_H
Ответ 5
Не связанный с проблемой ОП, но для любого другого ученика C++, который наткнулся на это, я получил эту ошибку по другой причине. Если ваш родительский класс является шаблонным, вам нужно указать имя типа в дочернем классе:
#include "Parent.h"
template <typename ChildType>
class Child : public Parent<ChildType> { // <ChildType> is important here
};