【发布时间】:2013-07-22 05:18:51
【问题描述】:
我的代码中有一个案例,我想使用对象切片,但我正在尝试确定这样做是否安全或明智。为了确定这一点,我运行了以下示例:
#include <iostream>
using namespace std;
class Dog{
public:
Dog( int x )
:x{x}
{
};
int x;
};
class Spaniel: public Dog{
public:
Spaniel( int x, int y )
:Dog{x}, y{y}
{
}
int y;
};
class Green{
public:
Green( int q )
:q{q}
{
}
int q;
};
class GreenSpaniel: public Spaniel, public Green{
public:
GreenSpaniel( int x, int y, int q, int z )
:Spaniel{x,y}, Green{q}, z{z}
{
}
int z;
};
int main(){
GreenSpaniel jerry{ 1,2,3,4 };
Green fred = jerry;
cout << fred.q << endl; //correctly displays "3"
return 0;
}
我希望它返回 1,因为基类不是最顶层(根),但它显示 3。所以,我的问题是它为什么/如何显示正确答案,这是一个安全实践?如果任何课程都有虚拟表,您的答案将如何变化?如果您认为它不安全,您是否有任何解决方法可以从派生对象复制非根基础对象?
我在 gcc 4.6.3 下的 linux 中使用以下命令运行它:
g++ -std=c++0x main.cc
【问题讨论】:
-
它可能既不安全也不聪明,但它是确定性的:
Green复制构造函数复制您的jerry对象的Green子对象,其中q设置为3。 -
您是否知道标准的一部分解决了这个问题(即保证其确定性?)
-
不,这不是一种安全的做法,人们通常喜欢避免切片,因为它会带来一些问题。尽管您的程序定义明确(请参阅下面的答案)
-
将成员变量公开是不安全的做法,它将通过赋值静默(没有错误或警告)被覆盖(通常不是我们所做的)。
-
C++11 4.10/3(指针转换),我想说。
标签: c++ c++11 multiple-inheritance object-slicing