使用基类对象来表示其派生类对象

时间:2009-06-18 14:10:32

标签: c++

我需要一种方法让单个变量表示从同一基类派生的两种对象。

这有点难以描述,但我会尽力而为:

说基类:

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都是很棒的提示。

5 个答案:

答案 0 :(得分:8)

你可以做到这一点。问题是类的继承修饰符是privateMost 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;
};