复制构造函数初始化列表 [英] Copy constructor initialization lists

查看:122
本文介绍了复制构造函数初始化列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I know that if you leave a member out of an initialization list in a no-arg constructor, the default constructor of that member will be called.

执行复制构造函数同样调用成员的副本构造函数,还是也调用默认构造函数?

Do copy constructors likewise call the copy constructor of the members, or do they also call the default 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()?
}


推荐答案

显式定义的副本构造函数

Explicitly-defined copy constructors do not call copy constructors for the members.

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

When you enter the body of a constructor, every member of that class will be initialized. That is, once you get to { you are guaranteed that all your members have been initialized.

除非指定,否则成员将按照它们在类中出现的顺序进行默认初始化。(如果不能这样,则程序的格式不正确。)因此,如果您定义自己的副本构造函数,那么现在就可以了

Unless specified, members are default-initialized in the order they appear in the class. (And if they can't be, the program is ill-formed.) So if you define your own copy constructor, it's now up to you to call any member copy constructors as desired.

这里是一个小程序,您可以将其复制粘贴到某个地方并弄乱:

Here is a small program you can copy-paste somewhere and mess around with:

#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&)

请注意,它是默认初始化 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.

如果我们重新引入 Baz 的复制构造函数,并且明确复制单个成员:

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&)

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

As you can see, once you explicitly declare a copy-constructor you are responsible for the copying of all class members; it's your constructor now.

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

This applies for all constructors, including move constructors.

这篇关于复制构造函数初始化列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆