如果我将一个成员存储为一个对象,我会在构建期间招致一个对象副本吗?

时间:2009-09-03 20:46:28

标签: c++ pointers dependency-injection

如果Door的构造函数如下所示:

Door::Door(Doorknob doorknob) : m_doorknob(doorknob) { }

然后你会像这样实例Door

Doorknob doorknob;
Door door(doorknob);  // Does an object copy of doorknob occur here?

似乎您将Doorknob存储为指针,您可以明确地避免复制:

Door::Door(Doorknob * doorknob_ptr) : m_doorknob_ptr(doorknob_ptr) { }

像这样实例化Door

Door door(new Doorknob);

但是现在你必须确保delete doorknob内部Door的析构函数,这看起来很难看。

首选方法是什么?

2 个答案:

答案 0 :(得分:5)

更好的方法是传递const引用:

Door::Door(const Doorknob& doorknob) : m_doorknob(doorknob) { }

否则Doorknob的副本将传递给构造函数并用作m_doorknob构造函数的参数。

答案 1 :(得分:2)

比最小化复制构造函数调用的数量更重要的是您的代码正确地为问题空间建模。

门拥有门把手;即DoorKnob的生命周期与Door的生命周期相同。因此,Door应该管理Doorknob的生命周期。

出于这个原因,第二种解决方案不是优选的。您依靠客户端来制造Doorknob对象,然后存储指针,这违反了RAII

您的第一个解决方案是可以接受的,但正如您所注意到的那样,作为Doorknob对象的不必要副本的问题,因为副本作为参数。

理想的解决方案是让contructor接受引用,就像@ pingw33n的解决方案一样。或者,因为在门外建造门把手可能没有意义,所以让门构造器创建门。