2010-04-30 67 views
3

让我们假设我有一个C++类,它已经正确实现了一个拷贝构造函数和一个overloaded =运算符。通过正确实现我的意思是他们工作和执行深层副本:这个构造函数是可以接受的练习吗?

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

现在让我们说我有这样的构造,以及:

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

我的问题是将上述构造是可以接受的做法?这是我继承和维护的代码。

+0

在我的代码中,我计划使用复制构造函数,而不是构造函数fyi。 – Robb 2010-04-30 16:46:42

回答

7

我会说“不”,有以下原因:

  • 传统的拷贝构造函数接受它的参数作为一个const参考,不作为一个指针。
  • 即使您接受指针作为参数,它确实应该是const Class1*来表示参数不会被修改。
  • 这个拷贝构造函数是低效(或将无法正常工作!),因为Class1所有成员都默认初始化,然后使用operator=
  • operator=复制有同样的问题;它应该接受一个引用,而不是一个指针。

operator=中“复制”复制构造函数的传统方法是copy-and-swap idiom。我会建议以这种方式实施这个课程。

+0

非常好,我们会说。谢谢 – Robb 2010-04-30 16:51:24

+0

请记住,做复制和交换不能解决任何上述问题。特别是,所提到的低效率仍然存在。尽管如此,copy-and-swap在设计表现出强大的异常保证的类中很有用,所以这是一个很好的练习。 – 2010-04-30 17:43:48

2

就我个人而言,我认为这不是好习惯。

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

没有理由让指针指向非const,并且如果您有可用的指向该类的指针,则不容易取消引用它,并且清楚地声明您希望使用复制构造函数复制对象。

同样,对于非标准赋值运算符,为什么在正确解引用的时候允许从指针分配指针更清晰和更习惯?

1

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

赋值运算符和需要指针类型构造 - 它可以用于隐式转换特别构造 - 被真的要蒙混过关的事情,站在创造意想不到的副本,它不仅可能是一个性能的机会很高问题,但它可能会导致错误。

我想不出有什么好的理由,为什么你会想要在指向类型的指针和类型本身之间进行转换 - 甚至是显式的。内置的方法是解除对象的引用。我认为可能有一些具体的情况,我不能想到这种事情可能是必要的或是一个好主意,但我真的怀疑它。当然,我强烈建议不要这样做,除非你有这样的具体和充分的理由。

2

我认为比迄今为止讨论的更重要的问题是,您的非标准赋值运算符不会停止编译器生成标准赋值运算符。既然你已经决定你需要创建一个赋值操作符(因为你创建了拷贝构造函数,所以下注不错),默认值几乎肯定是不够的。因此,对于几乎任何人来说,这个类的用户在看起来非常基本和标准的对象使用过程中可能会成为这个问题的牺牲品。

相关问题