从重载的复制构造函数中调用默认的复制构造函数

Ala*_*ing 11 c++ constructor deep-copy copy-constructor shared-ptr

我需要编写一个复制构造函数,深度复制一个内容std::shared_ptr.但是,int a, b, c, d, e;在类中还定义了一堆变量.有没有办法在我的新重载的代码中生成默认的复制构造函数代码(或调用默认的复制构造函数).

这是一个带有注释的代码片段,希望能够澄清问题.

class Foo {
public:
     Foo() {}
     Foo(Foo const & other);
     ...
private:
     int a, b, c, d, e;
     std::shared_ptr<Bla> p;
};

Foo::Foo(Foo const & other) {
    p.reset(new Bla(*other.p));

    // Can I avoid having to write the default copy constructor code below
    a = other.a;
    b = other.b;
    c = other.c;
    d = other.d;
    e = other.e;
}
Run Code Online (Sandbox Code Playgroud)

Set*_*gie 7

我一直认为像这样的问题应该至少有一个答案引用未来读者的标准,所以在这里.

该标准的§12.8.4规定:

如果类定义没有显式声明复制构造函数,则会隐式声明一个.

这意味着,当一个类定义明确声明拷贝构造函数,一个是隐式声明.因此,如果您明确声明一个,则隐式的不存在,因此您无法调用它.

  • 不,标准的引用并不意味着这一点. (8认同)
  • 是的,这对你来说是个很好的猜测(就妈妈而言),但这不是保证,标准就是定义保证. (3认同)
  • “如果不是 A 则 B”并不意味着“如果 A 则不是 B”。但我知道你的意思,在这种情况下“如果 A 则不是 B”也是正确的。 (2认同)

Che*_*Alf 5

这是问题代码,因为我正在写这个:

class Foo {
public:
     Foo() {}
     Foo(Foo const & other);
     ...
private:
     int a, b, c, d, e;
     std::shared_ptr<Bla> p;
};

Foo::Foo(Foo const & other) {
    p.reset(new Bla(other.p));

    // Can I avoid having to write the default copy constructor code below
    a = other.a;
    b = other.b;
    c = other.c;
    d = other.d;
    e = other.e;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码很可能是错误的,因为

  1. 默认的构造函数的叶子a,b,c,de未初始化,并

  2. 代码不负责分配复制,并且

  3. 表达式new Bla(other.p)要求Bla有一个构造函数取一个std::shared_ptr<Bla>,这是极不可能的.

有了std::shared_ptr这必须是C++ 11的代码,以便在形式上正确的语言明智的.但是,我相信它只是使用编译器可用的代码.所以我认为相关的C++标准是C++ 98,并对C++ 03修正版进行了技术修正.

您可以轻松利用内置(生成)的复制初始化,即使在C++ 98中也是如此

namespace detail {
    struct AutoClonedBla {
        std::shared_ptr<Bla> p;

        AutoClonedBla( Bla* pNew ): p( pNew ) {}

        AutoClonedBla( AutoClonedBla const& other )
            : p( new Bla( *other.p ) )
        {}

        void swap( AutoClonedBla& other )
        {
            using std::swap;
            swap( p, other.p );
        }

        AutoClonedBla& operator=( AutoClonedBla other )
        {
            other.swap( *this );
            return *this;
        }
    };
}

class Foo {
public:
     Foo(): a(), b(), c(), d(), e(), autoP( new Bla ) {}
     // Copy constructor generated by compiler, OK.

private:
     int                      a, b, c, d, e;
     detail::AutoClonedBla    autoP;
};
Run Code Online (Sandbox Code Playgroud)

请注意,此代码在默认构造函数中正确初始化,确实负责复制赋值(使用交换习惯用法),并且不需要特殊的智能指针识别Bla构造函数,而只是使用普通的Bla复制构造函数来复制.