繁体   English   中英

为什么切片非根基类会产生正确的答案?

[英]Why does slicing a non-root base class produce the correct answer?

我的代码中有一个案例,我想使用对象切片,但是我试图确定这样做是安全还是明智的。 为了确定这一点,我运行了以下示例:

#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。所以,我的问题是为什么/如何显示正确的答案, 这是安全的做法吗? 如果任何类都有虚拟表,您的答案将如何变化? 如果您认为它不安全,那么您是否有任何变通办法来从派生对象复制非根基础对象?

我在Linux上的gcc 4.6.3下使用以下命令运行了该命令:

g++ -std=c++0x main.cc

发生的情况是,fred是使用编译器综合的副本构造函数构造的,该构造函数将const Green&作为参数。 它执行jerry的Green部分内容的浅表副本。

如果您使用过,将会看到相同的结果

const Green& fred = jerry;

如果没有进行复制,则通过将其命名为fred访问jerry的jerry部分。

至于问题的另一部分,您的设计没有什么不安全的,只是它是“复杂的”,您需要了解正在发生的事情。 您可能需要阅读页面和相关页面,以进行有关该主题的讨论。

当然,您可以定义自己的具有不同行为的副本构造函数/运算符。 或者您可以禁止编译器生成它们

处理这些问题的传统方法是声明一个私有副本构造函数和副本分配,然后记录为什么这样做。 C ++ 2011中引入了一个新的替代方法,该方法声明了一个拷贝构造函数和一个拷贝赋值运算符,但是将它们都标记为已删除。 从不可复制派生更简单明了,并且不需要其他文档。

资源

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM