2013-02-27 104 views
1

以下代码给出的编译错误为: “无法从第1行中的'Cloneable *'转换为'AClass *'”。 据我所知,与编译时间和运行时多态的概念。但我没有一个具体的推理在此。善良的帮助。多态性:代码中的Compliation错误需要解释

struct Cloneable 
{ 
virtual Cloneable* clone() 
    { 
    cout << "Cloneable"; 
    return new Cloneable; 
    } 

    virtual ~Cloneable() {} 
}; 


struct AClass : public Cloneable 
{ 
    virtual AClass* clone() 
    { 
    cout << "AClass"; 
    return new AClass; 
    } 
}; 

int main() 
{ 
Cloneable* s1 = new AClass; 
AClass* s2 = s1->clone();  //Line 1 
return 0; 
} 

回答

1

基本上,当你存储新ACLASS *在你的基类指针,调用克隆将是一个Cloneable的*,这将需要向下转换成ACLASS *,这可能并不总是安全的结果。因此,编译器需要一个dynamic_cast()

+0

@muhmud ...这个代码将正常工作,如果我使用的static_cast()(基类指针类型强制转换为派生类指针类型).Modifying行1为:ACLASS * S2 =的static_cast (S1 - > clone());我真正想知道的是,编译器如何解释这段代码。 – user2100866 2013-02-27 19:31:05

+0

@ user2100866 - 你应该看看这个 - http://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast。 dynamic_cast()'在向下转换过程中执行运行时检查,可以防止未定义的行为。 – muhmud 2013-02-27 20:20:52

1

虽然它可能只是使它“工作”与施放它是非常危险的,你在做什么。您忘记删除两个动态分配的对象。 “隐藏动态内存分配”也不是这么好,特别是你不会在任何地方删除它。使用std :: unique_ptr或std :: shared_ptr或者只是简单地在堆栈上分配对象会简单得多。

编辑:我不先给予直接的答案道歉:

AClass* s2 = dynamic_cast<AClass*>(s1->clone()); 
+0

使之工作之前,我想知道代码流。 – user2100866 2013-02-27 19:24:43

1

您在Cloneable指针调用clone()。该方法返回一个Cloneable*,所以你需要这样的:

Cloneable* s2 = s1->clone(); 

这将实例化一个AClass。这是使用这种克隆语言的标准方式。如果您正确使用多态性,那么应该有一个Cloneable*或一个AClass*。因此,您通常也会从AClass::clone()返回Cloneable*。当然,最好还是返回一个智能指针。

struct AClass 
{ 
    virtual std::unique_ptr<Cloneable> clone(); 
}; 

struct AClass : public Cloneable 
{ 
    virtual std::unique_ptr<Cloneable> clone(); 
};