2016-10-04 154 views
1

我有此类结构,其中D类和CLASSE祖父母是相同C++使用继承父类

classB : classA; 
classC : classA; 

classD : classB; 
classE : classC; 

然后我需要传递对象classF

classF : classA; 
function(classF *func); 
的函数转换成一对象类

是否可以将类型为classD和classE的对象传递给需要类型为classF的函数? 样本实施如下: 是否有可能只投给他们的共同祖父母?

classD *d = new classD(); 
classE *e = new classE(); 

classA *func = (classA*)d; 
function(func); 

func = (classA*)e; 
function(func); 
+1

请显示真实密码。在这种情况下,你应该使用'static_cast'。 –

+3

如果'classF'是必需的,你需要'classF'。如果'classA'提供'function(...)'中需要的所有内容,则相应地更改参数类型。 – grek40

+0

这取决于什么功能。它可以调用classF的特定方法。 – Daniele

回答

3

不,不,另一次没有。

,根本不符合要求的线是这样的:

function(func); 

这需要向下转换,即 - 一个从父类到它的子类铸造。 downcast不会隐式发生,这意味着该行不会编译(但是您提供了编译代码,您已经知道这一点)。以下将编译:

function((classF*)func); 

但你不应该使用它。 downcast的结果是未定义的,除非该引用最初属于该类型。所以,这是好的:

classF *f = new classF(); 
func = (classA*) f; 
function((classF*)func); 

但是,这并不:

classB *b = new classB(); 
func = (classA*) b; 
function((classF*)func); 

编辑如果使用专用的C++类型转换操作dynamic_cast进行丧气添加

,那么代码在运行时,确保羽化是正确的。所以:

classF *f = new classF(); 
func = (classA*) f; 
classF *newf = dynamic_cast<classF *>(func); // Okay 
classB *b = new classB(); 
func = (classA*) b; 
newf = dynamic_cast<classF *>(func); // newf is now NULL 

这允许运行时检查你没有犯过错。

就我个人而言,我喜欢从不依赖于实际设计,仅用于验证。在这种情况下,动态转换引用而不是指针会更好。动态转换不正确的指针会导致NULL。动态投不正确的引用抛出一个异常:

classF *f = new classF(); 
func = (classA*) f; 
classF *newf = &dynamic_cast<classF &>(*func); // Okay 
classB *b = new classB(); 
func = (classA*) b; 
newf = &dynamic_cast<classF &>(*func); // Throws an exception 
2

如果你想发挥一个classF指针,你应该传递一个classF指针。您的代码甚至不应该这样进行编译,因为功能的需要classF,你给它一个classA

你能得到这个与类转换为classF,你不应该这样做编译。这会让你进入未定义的行为状态,因为你基本上会对你的编译器说谎,并说“这个其他类是classF指针”,这不会是真的。

你总是可以放心地做它转换为基类的指针(像你在你的榜样与铸造classA做)

你也应该切换从C风格的强制转换成C++风格的转换(如static_castdynamic_cast)。这也可以帮助你在你的情况。通过动态演员,你可以安全地将一个班级转化为一个训练有素的班级。

像这样:

class A {}; 

class B : public A {}; 
class C : public A {}; 

A* b-obj = new B; 
A* c-obj = new C; 

现在都c-objb-obj是指向A,所以我们不知道了,如果他们是B或C.你可以用dynamic_cast

C* ptr = dynamic_cast<C*>(b-obj); //returns null because b-obj cannot be converted to C* 

C* ptr = dynamic_cast<C*>(c-obj); //does not return null 

检查此您的代码可以如下所示:

func = static_cast<A*>(e); // cast to base class. 
//later then. 
classF* funcF = dynamic_cast<F*>(func); 
if(funcF != NULL) 
{ 
    function(func); 
} 

c风格的演员阵容可能会有一些你可能不喜欢的副作用。所以强烈建议熟悉C++强制转换。