2009-06-18 3 views
2

Мне нужно, чтобы одна переменная представляла два вида объектов, полученных из одного и того же базового класса.Использование объекта базового класса для представления его объектов производного класса

Это своего рода трудно описать, но я буду стараться самое лучшее:

Say базовый класс:

class Rectangle 
{ 
    float w; 
    float h; 
    const float area() {return w*h;} 
}; 

И два производных класса:

class Poker : Rectangle 
{ 
    int style; // Diamond, Club, .... 
    int point; // A~10, J, Q, K 
}; 

class BusinessCard : Rectangle 
{ 
    string name; 
    string address; 
    string phone; 
}; 

Теперь это возможно объявить объект, который может быть либо покером, либо визитной карточкой?

«Потому что ниже использование является незаконным:

Rectangle* rec; 
rec = new Poker(); 
delete rec; 
rec = new BusinessCard(); 

полиморфизм может быть способом, но так как это хорошо только для изменения базового класса» атрибуты членов, мне нужен этот объект, чтобы быть в состоянии представить точно либо из производные объекты.

EDIT:

Спасибо за ответы на все вопросы. Наследование наследования, виртуальный деструктор и даже boost :: variant typedef - все это фантастические подсказки.

ответ

8

Вы можете это сделать. Проблема заключается в модификаторе наследования для классов private. Most of the time, private inheritance is not what you want to use. Вместо этого объявить его в явном виде public:

class Rectangle 
{ 
    float w; 
    float h; 
    const float area() {return w*h; }; // you missed a semicolon here, btw 
    virtual ~Rectangle() { } // to make `delete` work correctly 
}; 

class Poker : public Rectangle // note the public keyword 
{ 
    int style; // Diamond, Club, .... 
    int point; // A~10, J, Q, K 
}; 

class BusinessCard : public Rectangle 
{ 
    string name; 
    string address; 
    string phone; 
}; 

Тогда ваш фрагмент кода должен работать.

+1

И виртуальный деструктор ... – sharptooth

+0

Вы избили меня до него. =) –

+0

@sharptooth: в то время как это, вероятно, хорошая идея, это * не * требуется, чтобы этот фрагмент кода работал, поэтому я думаю, что это не имеет прямого отношения к вопросу. –

1

Я думаю, что вы, возможно, ищете многократное наследование, где объект иногда может быть Покером, а иногда и визитной карточкой.

Смотрите здесь для учебника:

http://www.deitel.com/articles/cplusplus_tutorials/20060225/MultipleInheritance/index.html

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

2

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

Не знаю, если я понимаю, что это правильно, но посмотреть на boost::variant

typedef boost::variant<Poker, BusinessCard> PokerOrBusinessCard 

Теперь вы можете получить доступ к производным классам с классом посетителя подталкивание вариант.

Возможно, это может быть решение.

3

Вам необходимо изменить классификатор для наследования для общественности.

class Poker : public Rectangle 
{ 
    int style; // Diamond, Club, .... 
    int point; // A~10, J, Q, K 
}; 

class BusinessCard : public Rectangle 
{ 
    string name; 
    string address; 
    string phone; 
}; 

- это то, что вы хотите.Теперь оба класса, BusinessCard и Poker имеют тип Rectangle.

1

Измените подклассы на использование общедоступного вывода и ваш код работает с некоторой очисткой. Вы также должны использовать виртуальные деструкторы, чтобы удаление работало правильно.

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