c++ - 复制构造函数初始化列表

标签 c++ copy-constructor

我知道,如果您在无参数构造函数中将一个成员排除在初始化列表之外,则会调用该成员的默认构造函数。

复制构造函数是否同样调用成员的复制构造函数,还是它们也调用默认构造函数?

class myClass {
  private:
    someClass a;
    someOtherClass b;
  public:
    myClass() : a(DEFAULT_A) {} //implied is b()
    myClass(const myClass& mc) : a(mc.a) {} //implied is b(mc.b)??? or is it b()?
}

最佳答案

显式定义的复制构造函数不会为成员调用复制构造函数。

当您进入构造函数的主体时,该类的每个成员都将被初始化。也就是说,一旦您到达 {,就可以保证您的所有成员都已初始化。

除非指定,否则成员会按照它们在类中出现的顺序进行默认初始化。(如果不能,则程序格式错误。)因此,如果您定义自己的复制构造函数,现在由您根据需要调用任何成员复制构造函数。

这是一个小程序,您可以在某处复制粘贴并随意使用:

#include <iostream>

class Foo {
public:
    Foo() {
        std::cout << "In Foo::Foo()" << std::endl;
    }

    Foo(const Foo& rhs) {
        std::cout << "In Foo::Foo(const Foo&)" << std::endl;
    }
};

class Bar {
public:
    Bar() {
        std::cout << "In Bar::Bar()" << std::endl;
    }

    Bar(const Bar& rhs) {
        std::cout << "In Bar::Bar(const Bar&)" << std::endl;
    }
};

class Baz {
public:
    Foo foo;
    Bar bar;

    Baz() {
        std::cout << "In Baz::Baz()" << std::endl;
    }

    Baz(const Baz& rhs) {
        std::cout << "In Baz::Baz(const Baz&)" << std::endl;
    }
};

int main() {
    Baz baz1;
    std::cout << "Copying..." << std::endl;
    Baz baz2(baz1);
}

按原样打印:

In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo()
In Bar::Bar()
In Baz::Baz(const Baz&)

Note that it's default-initializing the members of Baz.

By commenting out the explicit copy constructor, like:

/*
Baz(const Baz& rhs) {
    std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
*/

输出会变成这样:

In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo(const Foo&)
In Bar::Bar(const Bar&)

It calls the copy-constructor on both.

And if we reintroduce Baz's copy constructor and explicitly copy a single member:

Baz(const Baz& rhs) :
    foo(rhs.foo)
{
    std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}

我们得到:

In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo(const Foo&)
In Bar::Bar()
In Baz::Baz(const Baz&)

如您所见,一旦您明确声明了一个复制构造函数,就负责复制所有类成员;它现在是你的构造函数。

这适用于所有构造函数,包括移动构造函数。

关于c++ - 复制构造函数初始化列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/754729/

相关文章:

c++ - libvlc_video_set_subtitle_file 不工作

C++ 为什么调用复制构造函数?

c++ - 复制构造函数与返回值优化

c++ - linux上g++9.3.0 -O2的一个奇怪bug

c++ - 重载派生类中的比较运算符权私有(private)继承

具有动态内存的类的 C++ 五规则

c++ - 使用智能指针复制构造函数

c++ - 为什么删除了复制构造函数的结构不是 POD 类型?

c++ - Windows 事件的等效 boost

c++ - 如何从类中初始化数组并将值设置为第一个元素?