2009-04-14 187 views
10

我可以通过传递一个指针而不是const引用来写一个拷贝构造函数吗? (难道是确定的,如果我要确保我不会改变任何价值,但?)复制构造函数 - C++

像这样:

SampleClass::SampleClass(SampleClass* p) 
{ 
//do the necessary copy functionality 
} 

代替:

SampleClass::SampleClass(const SampleClass& copyObj) 
{ 
//do the necessary copy 
} 

在此先感谢。


谢谢大家。所以,如果我编写一个接受指针的构造函数(并认为这是我的拷贝构造函数),编译器仍然会提供默认的拷贝构造函数,在这种情况下,我的构造函数(我认为是我的拷贝构造函数)不会被调用,默认的拷贝构造函数会被调用。得到它了。

回答

1

号拷贝构造函数必须采取一个参考,不是指针,如果它是用于传递按值等有用。

4

你可以写一个构造函数指针作为参数。
但复制构造函数是我们给出的具体构造函数的名称。
将参数(最好是const但不是必需的)与参数相同的类的构造函数命名为复制构造函数,因为这是它的有效功能。

19

是的,您可以编写一个构造函数,该构造函数将指针指向该对象。但是,它不能称为复制构造函数。复制构造函数的定义要求您传递相同类的对象。如果你传递了其他任何东西,是的,这是一个构造函数,但不是复制构造函数。

1

根据定义,copy ctor使用const引用。虽然没有什么能够阻止你编写一个带指针的ctor,但它会引发一些在使用引用时不存在的问题 - 例如,如果传入一个空指针会发生什么?

1

拷贝构造函数需要一个参考,因为值参数需要进行复印,这会调用拷贝构造函数,这会使得它的参数的副本,它会调用拷贝构造函数,它...

1

你可以写一个这样的构造函数,但它在技术上不是一个拷贝构造函数。例如,STL容器仍然会使用编译器生成的拷贝构造函数(编译器会生成一个,因为您没有编写一个)。

2

除了它不是一个复制构造函数,编译器将生成复制构造函数,除非您明确禁用它,否则没有什么可以获得,也没有多少可以松动。一个空指针构造函数的正确语义是什么?这会给你的课堂用户增加什么? (提示:没有什么,如果她想从堆对象中构建出来,她只能解引用指针并使用常规的拷贝构造函数)。

1

拷贝构造函数在两种情况下被隐含使用:

  • 当你的类的实例是按值传递给函数。
  • 当你的类的一个实例被函数的值返回时。

正如其他人已经提到的,你可以写一个构造函数与描述的签名(或与一个const指针),但它不会在上述任何一种情况下使用。

-1

您可以编写一个完全有效的副本构造函数,并且仍然能够传递一个为NULL的引用。您可以测试NULL,但前提是您不使用构造函数初始化列表。

例子:

MyClass::MyClass(MyClass const& MyClassCopy) 
: somevar(MyClassCopy.somevar) // <- the init list goes here. 
{ 
    // If MyClassCopy is NULL, the initialization above is doomed! 
    // However we can check for NULL in the constructor body but 
    // the initialization list must be removed ... 
    if (&MyClassCopy == NULL) throw(std::runtime_error("NULL pointer!")); 
    somevar = MyClassCopy.somevar; 
} 

// I'll now do some very dangerous programming to 
// demonstrate one way that a NULL can get through ... 
MyClass* P = NULL; 
MyClass A(*P); // Bang, you're dead! 

据我所知,有没有办法从初始化列表里面检查NULL,所以如果你认为你可以用形势结束了,其中一个NULL获得通过,你必须在构造函数体中测试它,并从那里进行初始化。

不要忘记还有一些陷阱与::运算符=()函数来了解...

+1

你不能没有在该代码调用未定义的行为得到一个空引用。在事实没有用之后测试NULL,因为错误出现在其他代码中。事实上,编译器可以优化掉if(&MyClassCopy == NULL)这个测试,因为它不会发生在一个正确的程序中。 – 2011-11-03 21:28:43

+0

我同意解引用NULL指针是一个无效的操作,并且NULL的测试最好在取消引用操作之前完成。但是由于可以在运行时分配NULL,所以大多数编译器将允许您创建NULL引用,编译器无法检查它。或者为NULL优化一个测试。你可以用g ++来测试它,测试工作。 – Rob 2011-11-04 07:36:29

+0

经过一段时间的思考,你是对的,你必须在解引用操作之前测试null。事后的测试确实没有定义。 – Rob 2011-11-04 08:11:48