这个构造函数是否可以接受?

时间:2010-04-30 16:39:30

标签: c++ oop copy-constructor

假设我有一个正确实现了复制构造函数和重载=运算符的c ++类。通过适当实施,我的意思是他们正在工作并执行深层复制:

Class1::Class1(const Class1 &class1)
{
  // Perform copy
}
Class1& Class1::operator=(const Class1 *class1)
{
  // perform copy
  return *this;
}

现在让我说我也有这个构造函数:

Class1::Class1(Class1 *class1)
{
   *this = *class1;
}

我的问题是上述构造函数是否可以接受?这是我继承和维护的代码。

4 个答案:

答案 0 :(得分:7)

我会说,“不”,原因如下:

  • 传统的复制构造函数接受其参数作为const引用,而不是指针。
  • 即使您接受指针作为参数,它也应该const Class1*表示该参数不会被修改。
  • 此复制构造函数效率低(或不起作用!),因为Class1的所有成员都是默认初始化的,然后使用operator=
  • 复制
  • operator=有同样的问题;它应该接受引用,而不是指针。

operator=中“重复使用”复制构造函数的传统方法是copy-and-swap idiom。我建议那样实现这个类。

答案 1 :(得分:2)

我个人认为这不是好习惯。

对于构造函数,很难想象从指针到对象到对象本身的隐式转换是有用的。

没有理由将指针指向非const,并且如果你有指向类的指针,那么取消引用它并不困难,因此清楚地表明你想要使用复制构造函数复制对象的意图。

类似地,对于非标准赋值运算符,为什么在调用站点正确解除引用时允许从指针赋值更清晰且更惯用?

答案 2 :(得分:2)

我认为比目前讨论的问题更重要的一点是,非标准赋值运算符不会阻止编译器生成标准运算符。既然你已经决定需要创建一个赋值运算符(自从你创建了复制构造函数以来,这是一个不错的选择),默认情况几乎肯定是不够的。因此,对于几乎任何人来说,这个类的用户可能会成为这个问题的牺牲品。

答案 3 :(得分:1)

对象和指向对象的指针是两个非常不同的东西。通常,当您传递对象时,您希望它们将被复制(尽管理想情况下,函数会尽可能采用const引用来减少/消除不必要的副本)。当您传递指针时,您不希望发生任何复制。你正在传递一个指向特定对象的指针,并且根据代码,处理该特定对象而不是它的副本真的很重要。

指向类型指针的赋值运算符和构造函数 - 尤其是可用于隐式转换的构造函数 - 真的会混淆事物并且很有可能创建非预期的副本,这不仅仅是可能是一个性能问题,但它可能会导致错误。

我想不出有什么理由可以让你想要在指向类型的指针和隐含的类型本身之间进行转换 - 甚至是显式的。内置的方法是取消引用对象。我想可能存在一些特定情况,我无法想到这种事情可能是必要的或者是一个好主意,但我真的对此表示怀疑。当然,除非你有充分理由这样做,否则我强烈建议不要这样做。