10

为什么复制构造函数的参数是引用而不是指针?

为什么我们不能使用指针呢?

4

6 回答 6

13

原因有很多:

  1. 引用不能为 NULL。好的,可以创建 NULL 引用,但也可以将 astd::vector<int>*转换为std::vector<SomeType>*. 这并不意味着这样的演员表已经定义了行为。也没有创建 NULL 引用。指针在设置为 NULL 时已定义行为;参考没有。因此,引用总是希望引用实际对象。

  2. 变量和临时变量不能隐式转换为指向其类型的指针。出于显而易见的原因。我们不希望指向临时对象的指针到处乱跑,这就是标准明确禁止这样做的原因(至少当编译器可以告诉您正在这样做时)。但是我们可以引用它们;这些是隐式创建的。

  3. 由于第 2 点,使用指针而不是引用将要求每个复制操作都使用地址运算符(&)。哦等等,C++ 委员会愚蠢地允许它超载。因此,任何复制操作都需要实际使用std::addressofC++11 特性来获取地址。所以每个副本都需要看起来像Type t{std::addressof(v)};或者你可以只使用references

于 2013-09-04T10:53:21.123 回答
8

这只是命名法。您也可以使用指针,但这称为转换构造函数

如果您考虑一下,这是有道理的,因为您将一个对象复制到另一个对象(因此,“副本”)。不是来自指向对象的指针。如果它是一个指针,它不会进行复制,因为您不是将指针复制到对象,而是将指针指向的对象复制到您的对象。

于 2013-09-04T10:38:00.323 回答
5

因为这被标准所否定。

引用 C++ 草案标准 n3376 - 第 12.8.2 节:

类 X 的非模板构造函数是复制构造函数,如果它的第一个参数是X&、const X&、volatile X& 或 const volatile X&类型,并且要么没有其他参数,要么所有其他参数都有默认参数

于 2013-09-04T10:36:32.283 回答
5

为什么它应该是一个指针?空指针没有意义。并且使用指针不允许复制临时对象,因此您不能执行以下操作:

MyClass
func()
{
    //  ...
    return MyClass(...);
}

可以定义一个带有指针的构造函数。但它不会是复制构造函数,因为它不能用于上述情况。它不会阻止编译器生成复制构造函数。

于 2013-09-04T10:41:18.050 回答
1

因为指针可能是nullptr必须检查的,而临时对象不能有指向它们的指针。

于 2013-09-04T10:36:10.487 回答
1

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

于 2016-07-29T07:50:39.153 回答