为什么在C ++中需要“对象切片”?为什么允许?有更多的错误? [英] Why is 'object slice' needed in C++ ? Why it is allowed ? For more bugs?
问题描述
为什么C ++标准允许对象切片?
Why C++ standard allow object slice ?
请不要向我解释c ++对象切片的概念,因为我知道。
Please don't explain c++ object slice concept to me as I knew that.
这个c ++特性(对象切片)设计背后的意图是什么?
I am just wondering what's the intention behind this c++ feature(object slice) design ?
为新手提供更多错误?
?
下面是一个标准和基本的例子:
Below is just a standard and basic slice example:
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
}
================================= ============================
阅读所有的答案和评论后,我想我应该更好地表达我的问题,但在这里它来:
================================================================================= After reading all the answers and comments I think I should express my question better in the first place but here it comes:
当有一个is-a关系公共继承),而不是私人/保护继承,你可以做以下:
When there is a is-a relationship(public inheritnace), instead of private/protected inheritance , you can do the following:
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
}
众所周知,
注意1,2和3 需要
如果您使用的是私有/保护继承,那么所有这些都将得到编译错误:
Note 1, 2 and 3 NEED is-a relationship to work.
If you are using private/protect inheritance, you will get compile error for all of them :
'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吗?
So my question(original intention) was to ask would it be better if c++ standard make 1 a compile error while keep allowing 2 and 3 ?
希望我这次更好地表达我的问题。
Hope I have expressed my question better this time.
感谢
推荐答案
由于是-a
关系,所以允许。
>公开 1 从基本
派生派生
编译器 Derived
是 c> 。因此,应该允许这样做:
When you publicly1 derive Derived
from Base
, you're annoucing to the compiler that Derived
is a Base
. Hence it should be allowed to do this:
Base base = derived;
,然后使用 base
即:
base.message(); //calls Base::message();
阅读:
- Is-A Relationship
1。如果您私下地从 Base
中派生派生
,那么它是 has-a
关系。这是一种组成。阅读此和这。
1. If you privately derive Derived
from Base
, then it is has-a
relationship. That is sort of composition. Read this and this.
但是,在你的情况下,如果你不想切片,那么你可以这样做:
However, in your case, if you don't want slicing, then you can do this:
Base & base = derived;
base.message(); //calls Derived::message();
从您的评论:
From your comment :
不能更好的C ++防止对象切片,而只允许指针/引用的工作is-a relationshp ???
Wouldn't it better for C++ to prevent object slicing while only allow the pointer/reference to work for is-a relationshp ???
否。如果基数具有虚函数,指针和引用不维持 is-a
关系。
No. Pointer and Reference doesn't maintain is-a
relationship if the base has virtual function(s).
Base *pBase = &derived;
pBase->message(); //doesn't call Base::message().
//that indicates, pBase is not a pointer to object of Base type.
当你想让一个类型的一个对象的行为像它的基类型的对象,调用 is-a
关系。如果你使用基本类型的指针或引用,那么它不会调用 Base :: message()
,这表明,指针或引用不像指针,引用 类型的对象。
When you want one object of one type to behave like an object of it's base type, then that is called is-a
relationship. If you use pointer or reference of base type, then it will not call the Base::message()
, which indicates, pointer or reference doesn't have like a pointer or reference to an object of base type.
这篇关于为什么在C ++中需要“对象切片”?为什么允许?有更多的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!