【问题标题】:Why can't we use pass by pointer in copy constructor in c++?为什么我们不能在 C++ 的复制构造函数中使用指针传递?
【发布时间】:2015-03-10 00:03:34
【问题描述】:

我知道 c++ 中复制构造函数的一般语法可以参考。 但是,我怀疑如果我们使用指针类型而不是引用会发生什么?为什么我们不在 Copy 构造函数中使用指针传递机制? 它的主要缺点是什么?

【问题讨论】:

  • 编写一个接受指针而不是引用的构造函数没有问题。它只是不是一个复制构造函数。它是一个带有指针的构造函数。你也可以问“为什么我们不能为复制构造函数传递 7 个字符串、12 个整数和 3 个向量?”
  • 一个在印度很受欢迎的面试问题 :-)

标签: c++ c++11 constructor copy-constructor


【解决方案1】:

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

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

不包括指针,因为引用的全部目的是“成为”对象的别名,而指针表示间接。无需深入研究有关语言设计的深奥细节,it's a semantic distinction that makes a lot of sense when you consider the syntactic differences between them。

你可以编写任何你想要的构造函数,如果你想要它可以接受一个指针,但它不会是一个“复制构造函数”。所有权语义可能非常不清楚和模糊,并且非常规,并且有点奇怪,这就是我们不这样做的原因。

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

 explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);

【讨论】:

  • 这个例子有点误导,因为它包括复制和移动构造函数。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    bigmath a = 14;
    
    bigmath answer(a * 3);
    

    你不能取表达式a * 3的地址,所以你仍然需要一个const bigmath &版本的对象。

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

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

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

    【讨论】:

    • 不,你不能。那将不是一个复制构造函数。标准对此很清楚。
    • 什么,它不能编译,或者如果它接受 const bigmath & 对象,它根本就不是一个正确的复制构造函数?
    • @MatsPetersson:请参阅我的回答中引用的标准语言。它不需要是const bigmath&,但肯定不欢迎指针。
    • 对不起,明白了你的意思,我已经编辑以更正措辞(两次,使其更清晰)
    【解决方案4】:

    根据我的说法,复制构造函数的标准使用引用,但是引用和指针都会给出相同的输出,但是每当你将 nullptr 分配给使用引用的对象时(TestConstrutor obj2 = nullptr)它不会允许,但如果你作为指针传递,它会工作但它会崩溃,因为你不能将空指针分配给对象。

    它会正常工作:- TestConstrutor(const TestConstrutor &obj) x = obj.x; y = obj.y; //它将调用TestConstrutor obj1(100,200);测试构造器 obj2 = obj1; TestConstrutor(const TestConstrutor *obj)x = obj->x; y = obj->y;// 会调用TestConstrutor obj3 = &obj2;

    它不允许:- TestConstrutor(const TestConstrutor &obj)x = obj.x; y = obj.y;//TestConstrutor obj2 = nullptr;

    它会低,但会崩溃:- TestConstrutor(const TestConstrutor &obj)x = obj.x; y = obj.y; TestConstrutor(const TestConstrutor *obj)x = obj->x; y = obj->y; // TestConstrutor obj2 = nullptr;

    【讨论】:

      猜你喜欢
      • 2014-07-25
      • 2019-02-16
      • 1970-01-01
      • 2015-05-28
      • 2012-07-06
      • 2020-11-16
      • 2021-10-13
      • 2016-04-13
      相关资源
      最近更新 更多