2015-04-13 2 views
0

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

class Base{ 
    void dosomestuff(Derived instanceOfDerived) 
    { 
     //Something 
    } 
}; 

class Derived : public Base{ 
    //Something 
}; 

Базу нужен включать в производных, но декларирует производное это необходимо сначала заявление Базы. Объявление Forward не работает, потому что я не хочу использовать указатели.

Теперь мой вопрос: как это сделать без указателей? Возможно ли это? Или это единственная возможность сделать instanceOfDerived указателем?

+0

Имей извините. Вы совершенно правы. Я изменил пример, вопрос тот же. –

+2

Если вы хотите сослаться на то, что еще не определено, вам потребуется какая-то косвенность, как указатель или ссылка. (Обратите внимание, что вы не можете * использовать * производный класс внутри определения базового класса, вы можете ссылаться только на него по имени, вам нужно будет переместить определение функции.) – molbdnilo

ответ

2

Оригинальная версия вопроса спрашивает о наличии Base провести Derived как данные члена. Это, очевидно, невозможно. Это та же бесконечная проблема рекурсии (а Derived содержит Base субобъекта, поэтому Base будет рекурсивно содержать себя, и это будет черепах весь путь вниз.)

Пересмотренных вопрос спрашивает о том, функции-члена Base принимая по значению аргумента типа Derived. Это вполне возможно. Вам необходимо опережающее объявление о Derived и отложить определение функции члена до момента фактического определения Derived:

class Derived; 
class Base{ 
    void dosomestuff(Derived instanceOfDerived); // declaration only 
}; 

class Derived : public Base{ 
    //Something 
}; 

// out-of-class definition, so making it explicitly inline 
// to match the in-class definition semantics 
inline void Base::dosomestuff(Derived instanceOfDerived) { 
    //Something 
} 

Demo.

+0

Thats it. Благодарю. –

+0

полный сюрпризов ... приятно! –

2

Лучше сделать что-то вроде:

class Derived; 
class Base{ 
    void dosomestuff(Derived& instanceOfDerived) 
    { 
     //Something 
    } 
}; 

class Derived : public Base{ 
    //Something 
}; 

Я бы даже переместить тело метода dosomestuff к исходному коду CPP, где вы можете включить derived.h, а также base.h

баз. ч может выглядеть следующим образом:

#ifndef BASE_H_ 
#define BASE_H_ 

class Derived; 
class Base{ 
    void dosomestuff(const Derived& instanceOfDerived); 
}; 

#endif 

derived.h:

#ifndef DERIVED_H_ 
#define DERIVED_H_ 

#include "base.h" 

class Derived : public Base{ 
    //Something 
}; 

#endif 

base.cpp:

#include "base.h" 
#include "derived.h" 

void Base::dosomestuff(const Derived &instanceOfDerived) { 
    //Something 
} 
+0

Что делать, если они не хотят взять ссылку? –

+1

@JosephMansfield интерфейс Derived не может быть доступен из Base простым способом ... –

+0

Так что мне нужно использовать либо указатель, либо ссылку? Другого пути нет? –

0

Это означает, что ваша модель наследования не имеет смысла, если вы действительно хотите, чтобы сделать это. Помните «Убедитесь, что общедоступные модели наследования». "http://debian.fmi.uni-sofia.bg/~mrpaff/Effective%20C++/EC/EI35_FR.HTM Если вы сделаете их отношения наследования, это означает, что Derived является базой, а не« Derived является частью базы ». Вы можете создать 2 класса, чтобы сделать это, вместо того чтобы заставить их иметь отношения наследования.