Очень базовое наследование: ошибка: ожидаемое имя класса до '{токена

Я пытаюсь узнать 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

};