【问题标题】:Object as argument desctructor called but not constructor?对象作为参数析构函数被调用但不是构造函数?
【发布时间】:2019-12-16 22:51:42
【问题描述】:

(我来自C世界,我是C++初学者,所以简单回答问题)

在 c++ 中,参数是按值传递的。所以我尝试了下面的代码来了解它是如何工作的。

#include <iostream>

using namespace std;

class MyClass {
    int a;
    public:
        MyClass() {
            a = 0;
            cout<<"Default Constructor call\n"; }
        MyClass(int x) {
            a = x;
            cout<<"Constructor call\n"; }
        ~MyClass() {
            cout<<"Destructor call\n"; }
};

void myfoo(MyClass arg) {}

int main() {
    cout<<"Obj declaration\n";
    MyClass obj(10);
    cout<<"Function call\n";
    myfoo(obj);
    cout<<"End of main\n";
}

析构函数在函数结束时调用,构造函数在开始时不调用,因为没有构造函数MyClass(MyClass& xxx)。
那么,对象 arg 是如何在函数中构造的?一个简单的内存副本?总是有一个构造函数 MyClass(MyClass& xxx) 是否足够或更好

【问题讨论】:

  • '总是有一个 [copy] 构造函数是否足够或更好[...]?' 如答案中已经给出的那样,如果你没有提供一个,它将被隐式创建(但有一些例外,例如,如果您显式提供移动构造函数,或者如果您有不可复制的成员)。有时,这个默认的复制构造函数是合适的,有时不是。无论如何,请留意threefive的规则!

标签: c++


【解决方案1】:

并且构造函数一开始没有被调用

不完全正确。 copy constructor 被调用,这是由编译器隐式定义的。你可以自己定义一个:

MyClass(const MyClass& other) { cout << "Copy Constructor call\n"; }

隐式复制构造函数使用其复制构造函数复制每个成员。如果任何成员无法复制,则复制构造函数将被隐式删除。

可以显式禁用复制构造函数。在 C++11 之前的日子里,习惯用法是声明它是私有的。在现代 C++ 中,使用了 delete 关键字:

MyClass(const MyClass& other) = delete;

如果您这样做,代码将无法编译。

【讨论】:

  • 感谢您对隐式定义的回答。这是我需要的。 (Rq:我知道参数可以通过引用传递)。
  • @Stef1611 也请注意编辑;构造函数可能会被删除。
  • @Stef1611 请注意,当您的类具有用户定义的析构函数时,不推荐使用隐式复制构造函数(和复制赋值运算符)的定义。编译器将从现在开始执行此操作(C++17),但这可能会在未来的 C++ 版本中被删除。然后,您的代码将不再编译,并且表现得就像您在课堂上写了 MyClass(const MyClass&amp;) = delete;
  • @Stef1611 它只是调用任何成员的复制构造函数......并且原始类型(int,double,......)确实被复制了。
  • @all。我非常感谢您的简单回答。非常感谢。我接受了答案。
【解决方案2】:

因为没有构造函数MyClass(MyClass&amp; xxx)

这是不正确的,有一个带有签名MyClass(const MyClass&amp;) 的复制构造函数是编译器为你生成的。您可以提供自己的实现并将一些内容写入标准输出以查看。

MyClass(const MyClass& other) : a(other.a) {
        cout<<"Copy constructor call\n";
}

请注意,编译器为您生成特殊成员函数时的问题有点复杂。一开始可能太多了,但在某些时候你必须知道。一个很好的概述是this answer 中的表格。

【讨论】:

  • 或者,如果你想看看当真的没有复制构造函数时会发生什么,那么你可以做MyClass(const MyClass&amp;) = delete;
猜你喜欢
  • 2015-04-10
  • 1970-01-01
  • 1970-01-01
  • 2015-07-21
  • 2011-04-16
  • 2010-11-10
  • 2015-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多