2010-10-06 80 views
6

假设我有一个名为Base的类和从它派生的类SuperBase。鉴于add发生在一个Base*,要么这些是有效的:铸造到基类的有效性

SuperBase *super = new SuperBase; 
bases.add(super); 

或者

SuperBase *super = new SuperBase; 
bases.add((Base*)super); 
+0

我想不出一个好的问题题目,但我认为这样更好。 – GManNickG 2010-10-06 21:14:50

回答

9

的首部作品,只要SuperBaseBase公开导出,通过隐式转换源自对-base:

struct base { virtual ~base() {} }; 
struct derived : base {}; 

base* b = new derived; // okay 

第二个工程也是如此,但忽略了的保护:

struct derived : private base {}; // private base 

base* b = new derived; // not okay, base is private 
base* b = (base*)(new derived); // okay, but gross 

如果是private,你可能不应该投给它。

+1

+1对于未定义的行为 – jmasterx 2010-10-06 21:03:53

+0

使用'static_cast '而不是C风格转换'(Base *)'来确保你没有处理未定义的行为。 – 2010-10-06 21:06:29

+2

但事实并非如此! (至少在C++ 03中)。 C风格转换为无法访问的基础*可保证正常工作(即如同基础可访问)。结果指针是指向“Base”类型的基类子对象的有效指针,可以安全地使用它。即在这种情况下,C风格转换不是'reinterpret_cast',而是忽略保护的'static_cast'。当然,这仍然是一种糟糕的编程习惯,因为它忽略了保护,但它“起作用”。你为什么说这个行为是不确定的? – AnT 2010-10-06 21:43:01

1

这两个都是有效的 - 一个孩子可以用在一个地方,在这个地方有一个指向父母的引用/指针。这被称为多态性。

1

两者都是有效的,尽管不需要输入superBase*