为什么我们不能在c ++的拷贝构造函数中使用pass by pointer?

Shi*_*hat 2 c++ constructor copy-constructor c++11

我知道c ++中复制构造函数的一般语法会引用.但是,我怀疑如果我们使用指针类型而不是引用会发生什么?为什么我们不在Copy构造函数中使用pass by pointer机制?它有哪些主要缺点?

Bar*_*art 6

通过引用传递确保将实际对象传递给复制构造函数,而指针可以具有 NULL 值,并使构造函数失败。


Lig*_*ica 6

根据标准,不存在使用指针的复制构造函数:

[C++11: 12.8/2]:A类非模板的构造X是一个拷贝构造函数,如果它的第一个参数是类型X&,const X&,volatile X&const volatile X&,并且或者有没有其他参数,否则所有其他参数都默认参数(8.3.6).[..]

不包括指针,因为整个引用点是对象的"be"别名,而指针表示间接.如果不深入研究语言设计的深奥细节,那么当你考虑它们之间的语法差异时,它就是一种语义上的区别.

你可以编写你想要的任何构造函数,如果你想要它可以使用指针,但它不是一个"复制构造函数".对于所有权语义而言,它可能是非常不清楚和模糊的,并且是非常规的,并且有点奇怪,这就是我们不这样做的原因.

然而,这并不是闻所未闻; 考虑这个构造函数,这是在C++中实例化文件流的唯一方法,直到三年前和几年前:

 explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
Run Code Online (Sandbox Code Playgroud)


Mat*_*son 5

从技术上讲,您可以编写一个采用指针的构造函数(尽管根据规范的措辞,在这种情况下从技术上讲它不是复制构造函数)。但是,这会阻止您使用不可寻址的结果。假设我们有一个很大的数学课(多精度):

bigmath a = 14;

bigmath answer(a * 3);
Run Code Online (Sandbox Code Playgroud)

您无法获取表达式的地址a * 3,因此您仍然需要const bigmath &对象的版本。

(正如巴特所说,它还确保该对象是一个“正确的对象”,这也不会造成伤害 - 但对我来说,以上是一个更有力的论点)。

我也许应该补充一点,您为对象选择的构造函数的类型实际上取决于该类的作用和代表的内容。在某些对象中,复制绝对不是“好”的,而在其他情况下,例如类bigmath,复制构造函数绝对是一件好事。对于一个bigmath类,您可能还需要一个采用长整型、双精度型和字符串的构造函数。在某些情况下,拥有参考是没有意义的。在某些情况下,拥有 const 引用是没有意义的。在某些情况下,就像我说的,拥有复制构​​造函数是没有意义的。

通常,您可以通过添加取消引用操作将指针转换ptr为引用*ptr。由于编译器将获取该地址(以便它可以传递引用),因此它不会添加任何额外的代码来使用它。但为了方便起见,如果您有一个经常有指针指向的类并且想要复制它,那么拥有一个采用指针的构造函数确实可能有意义。我不完全确定那会在哪里,在我的头顶上。