将基类转换为其派生类之一?

时间:2011-11-12 00:13:21

标签: c++ class inheritance

是否有一个快捷方式来获取基类并将其转换为程序中的一个派生类?例如:

假设我有三个类,一个基类和两个派生类:

class cColor {
};

class cBlue : public cColor {
};

class cRed : public cColor {
};

然后我在我的程序中创建一个Color类:

int main(){
cColor unsaturated
return 0;
}

是否有某种方法可以将unsaturated从cColor类转换为cBlue或cRed类?类似的解决方案是将unsaturated存储在指针中,从指针创建一个新的cBlue或cRed类,然后删除unsaturated吗?

4 个答案:

答案 0 :(得分:2)

在创建对象后,无法更改对象的类型(构造和销毁除外,派生类对象暂时变为基类对象)。由于派生类对象可能比它们的基类更大,因此也无法使用它。

创建新派生对象,重置指针然后销毁基础对象的解决方法是有效的,如果没有其他人持有另一个指向基类的指针。如果有任何其他指针或对原始对象的引用,它将在之后悬空。但是如果你控制了类的唯一指针/引用(例如,如果你只通过一个从不泄漏指针或对真实对象的引用的单例代理对象来访问它),那么这个方法可以工作。

答案 1 :(得分:1)

我在C ++中有点生疏,但我相信你是对的。如果要将变量声明为cColor,则需要使用指针,并为其指定cBlue或cRed实例。

cColor* unsaturated = new cBlue();

答案 2 :(得分:0)

你可以做一个reinterpret_cast,但是,从基类到另一个类是非常不安全的,因为源类中不存在的目标类的数据成员不会被初始化为任何东西。

通常,您可以使用复制构造函数来解决此类情况。例如......

class cColor 
{ 
   cColor( ColorData );
   ColorData getData();
}; 

class cBlue : public cColor { 
}; 

class cRed : public cColor { 
}; 

则...

int main(){     
ColorData foo;
cColor unsaturated(foo);
rColor rcol(unsaturated.GetData());
return 0;     
}   

答案 3 :(得分:0)

你想要的是使用GoF页面305中的状态模式,你提出的是非常危险的是将基础对象的实例转换为派生类而不是它。不管怎么说,你可能会放弃你的简单例子,但是一旦派生类添加某个状态,或者改变vtable,它就会崩溃。 http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612/ref=sr_1_1?s=books&ie=UTF8&qid=1321058151&sr=1-1