【发布时间】:2011-09-22 14:32:40
【问题描述】:
为什么 C++ 标准允许对象切片?
请不要向我解释 c++ 对象切片的概念,因为我知道。
我只是想知道这个 c++ 特性(对象切片)设计背后的意图是什么?
给新手更多的bug?
c++ 防止对象切片不是更安全吗?
以下只是一个标准和基本的切片示例:
class Base{
public:
virtual void message()
{
MSG("Base ");
}
private:
int m_base;
};
class Derived : public Base{
public:
void message()
{
MSG("Derived ");
}
private:
int m_derive;
};
int main (void)
{
Derived dObj;
//dObj get the WELL KNOWN c++ slicing below
//evilDerivedOjb is just a Base object that cannot access m_derive
Base evilDerivedOjb = dObj; //evilDerivedObj is type Base
evilDerivedOjb.message(); //print "Baes" here of course just as c++ standard says
}
提前致谢。
================================================ =================================== 在阅读了所有答案和 cmets 之后,我认为我应该首先更好地表达我的问题,但它来了:
当存在 is-a 关系(公共继承),而不是私有/受保护继承时,您可以执行以下操作:
class Base{
public:
virtual void foo(){MSG("Base::foo");}
};
class Derived : public Base{
public:
virtual void foo(){MSG("Derived::foo");}
};
int main (void)
{
Base b;
Derived d;
b = d; //1
Base * pB = new Derived(); //2
Base& rB = d; //3
b.foo(); //Base::foo
pB->foo(); //Derived::foo
rB.foo(); //Derived::foo
}
众所周知,只有 2 和 3 是多态的,而一个是臭名昭著的对象 切片只会产生错误!
注意 1、2 和 3 NEED 是与工作的关系。
如果你使用私有/保护继承,你会得到所有的编译错误:
'type cast' : conversion from 'Derived *' to 'const Base &' exists, but is inaccessible
'type cast' : conversion from 'Derived *' to 'Base *' exists, but is inaccessible
'type cast' : conversion from 'Derived *' to 'Base &' exists, but is inaccessible
所以我的问题(初衷)是问如果c++标准会更好吗 在允许 2 和 3 的同时使 1 成为编译错误?
希望这次我能更好地表达我的问题。
谢谢
【问题讨论】:
-
不是。 Closevote 是错误的。
-
我猜投票是因为faq:“没有实际问题需要解决”。或者“伪装成问题的咆哮”。
-
咆哮伪装成一个问题...
-
@Gob00st:从好的方面来说,看到有人理解切片令人耳目一新。 :)
-
虽然措辞肯定更圆滑,但我认为这是一个足够公平的问题。投票重新开放。