怎么会出现调用了destructor,但之前没有constuctor呢?

问题描述 投票:0回答:2

我目前正在学习c++的面向对象特性。我写了一段代码来测试继承和多态的工作原理,这是代码的一部分。

    class Person
{
    public:
    Person()
    {
        cout << "Person constructed\n";
    }

    virtual void introduce()
    {
        cout << "hi from person" << endl;
    }

    ~Person()
    {
        cout << "Person destructed\n";
    }
};

class Student : public Person 
{
    public:
    Student()
    {
        cout << "Student constructed\n";
    }

    void introduce()
    {
        cout << "hi from student" << endl;
    }

    ~Student()
    {
        cout << "Student destructed\n";
    }
};

class Farmer : public Person 
{
    public:
    Farmer()
    {
        cout << "Farmer constructed\n";
    }

    void introduce()
    {
        cout << "hi from farmer" << endl;
    }

    ~Farmer()
    {
        cout << "Farmer destructed\n";
    }
};

class SJW : public Student
{
    public:
    SJW()
    {
        cout << "SJW constructed\n";
    }

    ~SJW()
    {
        cout << "SJW destructed\n";
    }
};

void whoisthis3(Person object)
{
    object.introduce();
}

int main()
{
    Student mark;
    SJW bigred;
    Farmer max;

    cout << endl;

    whoisthis3(mark);
    whoisthis3(max);
    whoisthis3(bigred);

    cout << endl;

    return 0;
}

这是代码中的一部分:

Person constructed
Student constructed
Person constructed
Student constructed
SJW constructed
Person constructed
Farmer constructed

hi from person
Person destructed
hi from person
Person destructed
hi from person
Person destructed

Farmer destructed
Person destructed
SJW destructed
Student destructed
Person destructed
Student destructed
Person destructed

这些派生类在开头和结尾都被构造和销毁了,就像预期的那样. 但为什么当whoisthis3方法执行时,会调用Person析构器呢?这里面到底发生了什么?

c++ oop destructor copy-constructor virtual-destructor
2个回答
1
投票
void whoisthis3(Person object)
{
    object.introduce();
}

这个函数接受它的 object 参数的值。 这意味着,一个新的 Person 对象是作为你传递给 whoisthis3. 由于你没有明确定义 Person的复制构造函数,这使用编译器生成的默认复制构造函数。 当函数结束时,它的 object 参数被销毁,你可以看到它的destructor打印的语句。


请注意,正如你所观察到的那样。whoisthis3 呼之欲出 Person::introduce 自从 object 是一个 Person而不是由它衍生的任何类型。 这通常被称为 对象切片.


2
投票

考虑以下简单的程序。

struct A 
{
    A() { std::cout << "construct A\n";  }
    ~A() { std::cout << "destruct A\n";  }  
};

int main()
{
  A a;
}

这个程序的打印结果是:

constructs A
destructs A

和预期的一样

现在让我们添加一个简单的函数。

void f(A a) {}

并调用它。

int main()
{
  A a;
  f(a);
}

然后我们看到:

construct A
destruct A
destruct A

现在我们看到: destruct A 从哪里来,相应的 construct A? 答案是,当你打电话 f,默认的复制构造函数被调用。如果你在copy-constructor中打印东西,像这样。

A(A const&) { std::cout << "copy-construct A\n"; }

然后你会得到这样的输出:

construct A
copy-construct A
destruct A
destruct A

这表明确实有两个对象被构造出来了 然后两个对象都被销毁。

另一方面,如果 f 像这样引用参数。

void f(A& a) {}

那么复制构造函数就不会被调用(因为没有进行复制),输出结果是:

construct A
destruct A
© www.soinside.com 2019 - 2024. All rights reserved.