【问题标题】:Implicit copy constructor and inheritance隐式复制构造函数和继承
【发布时间】:2014-11-18 20:52:31
【问题描述】:

我知道这种问题已经被问过很多次了,而且我已经阅读了关于它的不同答案,以及 ISO 标准的某些部分。
但是,对于 C++ 标准所期望的确切行为,我仍然需要一些说明

假设:

class A
{
    public:

        A( void ) {}
        A( const A & a ) {}
};

class B: public A
{
    public:

        B( void ) {}
        B( const B & b ) {}
};

我知道调用B 类的复制构造函数不会调用A 类的复制构造函数,并且我们可以使用初始化列表来做到这一点正确。

我也知道使用using 来继承构造函数。

但是对于没有显式提供复制构造函数而基类提供的派生类,标准究竟有什么要求:

class A
{
    public:

        A( void ) {}
        A( const A & a ) {}
};

class B: public A
{};

一直以为编译器会为B类隐式定义一个拷贝构造函数,从而隐藏了A类的拷贝构造函数,不会被调用。

但是,看起来情况并非如此,并且调用了 A 复制构造函数。
在 OS X 10.10 上使用 Clang 编译。

那么这是强制性的,还是可以由实现定义的,这意味着我们不应该依赖这种行为?

在 C++ 标准中,我发现了以下内容,但对我来说显然不是很清楚:

一个类的继承构造函数是隐式定义的 odr-used (3.2) 创建其类类型 (1.8) 的对象。一个 隐式定义的继承构造函数执行的集合 将由用户编写的类的初始化 具有 mem-initializer-list 的该类的内联构造函数,其 只有 mem-initializer 具有命名基础的 mem-initializer-id 在使用声明的嵌套名称说明符中表示的类 和如下指定的表达式列表,其中 函数体中的复合语句为空(12.6.2)。

我真的很乐意根据标准对此进行澄清,并考虑到多重继承。

【问题讨论】:

    标签: c++ inheritance constructor


    【解决方案1】:

    来自http://en.cppreference.com/w/cpp/language/copy_constructor(强调我的):

    隐式定义的复制构造函数

    如果隐式声明的复制构造函数既没有被删除也没有 微不足道,它被定义(即生成一个函数体并 编译)由编译器(如果使用了 odr)。对于联合类型, 隐式定义的复制构造函数复制对象表示 (如 std::memmove )。对于非联合类类型(类和结构), 构造函数执行对象基础的完整的成员复制 和非静态成员,按照初始化顺序,使用直接 初始化。

    所以编译器生成的复制构造函数似乎会调用基本的复制构造函数,就像它调用成员的复制构造函数一样。

    【讨论】:

    • 并且补充一点,继承构造函数与它完全没有关系,因为复制构造函数永远不会被继承,并且继承的构造函数不会阻止生成正确的复制构造函数。
    猜你喜欢
    • 2019-05-14
    • 1970-01-01
    • 2012-08-13
    • 2015-04-11
    • 2015-10-18
    • 2014-11-22
    相关资源
    最近更新 更多