当前位置:  开发笔记 > 编程语言 > 正文

复制构造函数初始化列表

如何解决《复制构造函数初始化列表》经验,为你挑选了1个好方法。

我知道如果你将一个成员从no-arg构造函数中的一个初始化列表中删除,那么将调用该成员的默认构造函数.

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

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()?
}

GManNickG.. 26

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

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

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

这是一个小程序,你可以复制粘贴到某个地方并乱用:

#include 

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.

通过注释掉显式复制构造函数,例如:

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

它在两者上调用copy-constructor.

如果我们重新引入Baz复制构造函数并显式复制一个成员:

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

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

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



1> GManNickG..:

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

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

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

这是一个小程序,你可以复制粘贴到某个地方并乱用:

#include 

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.

通过注释掉显式复制构造函数,例如:

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

它在两者上调用copy-constructor.

如果我们重新引入Baz复制构造函数并显式复制一个成员:

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

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

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

推荐阅读
李桂平2402851397
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有