1

У меня есть очень простые отношения между детьми и родителями, где OlderSon наследуется от родителя и родитель имеет указатель на его OlderSon, такие как:C++. Ребенок наследует от Родителя и включается как атрибут Parent

#ifndef PARENT_HXX 
#define PARENT_HXX 

#include <iostream> 
#include <string>  
//#include "OlderSon.hxx" 

class OlderSon; 

class Parent 
{ 
private : 
    OlderSon* _os; 
public :   
    int _age; 
    std::string _name; 

    Parent(){ 
     _name="parent name"; 
     _age=60; 
     //OlderSon* _os=new OlderSon(); 
    } 
}; 

#endif //PARENT_HXX 

и сын:

#ifndef OLDERSON_HXX 
#define OLDERSON_HXX 

#include <iostream> 
#include <string> 
#include "Parent.hxx" 


class OlderSon: public Parent 
{ 
public: 
    OlderSon(){ 
     _age=25; 
     _name="Olderson name"; 
    } 


}; 

#endif //OLDERSON_HXX 

Однако всякий раз, когда я пытаюсь раскомментировать строку, в которой указатель инициализируется OlderSon* _os=new OlderSon(); я получаю сообщение об ошибке:

Parent.hxx: In constructor ‘Parent::Parent()’: 
Parent.hxx:25:31: error: invalid use of incomplete type ‘struct OlderSon’ 
Parent.hxx:8:7: error: forward declaration of ‘struct OlderSon’ 

Я пробовал по-разному, а именно в том числе .hxx или путем объявления вперед, но ничего не помогает. Я думаю, это не очень сложная проблема, но она начинает расстраивать.
Любые идеи?
Спасибо заранее!

+0

Ваш сын является родителем? Я думаю, может быть, у вас должен быть базовый класс «Личность», а экземпляры Person «составлены» с другими экземплярами «Person» для формирования семейств. – Dennis

+0

Привет, теперь, когда вы указываете, что понятие сына/родителя не имеет большого смысла. Однако я попытался изменить имена на Son/Parent, чтобы объяснить это более четко. Фактически, эти классы являются частью метода Factory. Я хочу создать в игре как новые CHARACTERS, так и новые ITEMS. Я создал «ObjectFactory» (как родительский), который будет фильтровать, когда хочет создать ITEM или CHARACTER. И два подкласса 'ItemFactory' и' CharacterFactory', которые будут атрибутами 'ObjectFactory'. Тогда в зависимости от случая будет использоваться '.createObject (...)' либо 'ItemFactory', либо' CharacterFactory'. – lllllll

+0

Вам не нужно ничего фильтровать. ObjectFactory должен быть абстрактным, и если пользователь хочет создать элемент, ему следует просто использовать ItemFactory. – Dennis

ответ

0

почему вы не определяете дочерний указатель как родительский *;

class Parent 
{ 
private : 
    Parent* _os; 
. 
. 
. 
} 

Поскольку базовый класс ребенка является родительским.

+0

Благодарим вас за советы, хотя кажется, что они не исправляют все ошибки. – lllllll

+0

если вы меняете os на указатель на Parent, вы можете удалить непрозрачный указатель «class OlderSon;» в parent.hxx, который удаляет некоторые из ваших ошибок. – sardok

+0

Но тогда, как я могу использовать методы в классе «OlderSon»? Я должен бросать его каждый раз, когда я хочу его использовать? Кроме того, атрибуты (например, имя, возраст) будут принадлежать «Parent», а не «OlderSon», нет? – lllllll

4

Вы пытаетесь сделать невозможное. Вы можете исправить ошибку, переместив реализацию Parent:Parent в файл реализации, но ваш код по-прежнему будет катастрофическим.

Для создания родительского элемента потребуется построить OlderSon, и для построения OlderSon потребуется также создание родителя (так как OlderSon - это родительский элемент). У вас будет бесконечная рекурсия.

Вы не можете оба конструктора родителя позвонить по телефону и наоборот!

+0

Привет, спасибо за ответ. Я думал, что поскольку атрибут OlderSon в классе Parent является закрытым, он не наследуется OlderSon. Я изобразил это как:
Instantiate Parent -> Создает OlderSon как атрибут родителя, но частный атрибут не наследуется, поэтому он останавливает рекурсию. Я был неправ? – lllllll

+0

Это просто ограничения доступа. Они не делают член не существует. Производный класс * является * экземпляром родительского класса и обладает всеми его возможностями. (И подумайте об этом - что бы тогда была эта строка кода? Что произойдет, если вы выполнили какую-либо функцию-член базового класса, которая обратилась к такой переменной?) –

+0

Я думал, что строка создавала новую структуру данных только на основе унаследованных атрибутов из родительского класса. Имеет смысл, что это просто вопрос ограничения доступа, поскольку вы действительно можете применить его к классу Parent. Тогда я не уверен, что делать с этой концепцией. – lllllll

0

Конструктор Parent() использует конструктор для OlderSon(). Но он не знает OlderSon, потому что вы только переадресовали его. (что означает: я собираюсь использовать класс под названием OlderSon, но все, что вы (Parent.hxx) должны знать, это его имя, потому что в этом Header-файле я использую только указатель на него.) Попробуйте реализовать конструктор Parent() в файле Cxx, где вы включаете OlderSon.hxx

EDIT:

Я наблюдал за тем, что OlderSon наследуется от Родителя ... что приводит к бесконечной рекурсии, которая, вероятно, не то, что вы хотите.

+0

Я в принципе хотел иметь возможность реализовать его непосредственно в файле .hxx. Я думаю, вы правы в бесконечной рекурсии, как отметил @DavidSchwartz. Я думаю о том, как переделать это. – lllllll

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