我需要一种方法让单个变量表示从同一基类派生的两种对象。
这有点难以描述,但我会尽力而为:
说基类:
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();
多态性可能是一种方式,但由于它只适用于更改基类的成员属性,因此我需要此对象能够准确表示任一派生对象。
编辑:
感谢所有答案。公共继承,虚拟析构函数甚至boost :: variant typedef都是很棒的提示。
答案 0 :(得分: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 :(得分:3)
您需要将继承的限定符更改为public。
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;
};
是你想要的。现在这两个类,名片和扑克都是Rectangle类型。
答案 2 :(得分:2)
我需要这个对象才能 表示完全的任何一个 派生对象。
不知道我是否理解正确,但请查看boost::variant
typedef boost::variant<Poker, BusinessCard> PokerOrBusinessCard
现在,您可以使用boost变体访问者类访问派生类。
也许这可以解决问题。
答案 3 :(得分:1)
我认为您可能正在寻找的是多重继承,其中某个对象有时可以是扑克,有时也可以是BusinessCard。
请参阅此处获取教程:
http://www.deitel.com/articles/cplusplus_tutorials/20060225/MultipleInheritance/index.html
请注意,如果您愿意,您可以决定将其设置为一个或另一个,它不一定是所有时间,这可能满足您的需要。
答案 4 :(得分:1)
更改子类以使用公共派生,并且您的代码可以正常工作,并进行一些清理。您还应该使用虚拟析构函数,以便删除正常工作。
class Rectangle
{
float w;
float h;
const float area()
{
return w*h;
}
public:
virtual ~Rectangle(){};
};
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;
};