C++为什么在堆栈中构造对象后立即调用析构函数

C++ Why is the destructor immediately called after the object has been constructed in the stack?

本文关键字:调用 析构函数 对象 为什么 堆栈 C++      更新时间:2023-10-16

我有两个单元测试。在第一个中,我在堆栈中创建了对象myMovie。创建对象,然后立即调用析构函数。这会导致单元测试失败,因为当myMovie超出范围时,将再次调用析构函数。这会导致访问冲突。

但是,如果我在堆中创建对象,一切都会很好。为什么在堆栈中构造对象后立即调用析构函数?

第一个这样的:

TEST_METHOD(constructingMovieWithParametersStack)
    {
        _CrtMemState s1, s2, s3;
        _CrtMemCheckpoint(&s1);
        {
            Movie myMovie = Movie("firstName", "lastName", "title");
            // Why is the destructor is called here???
            string expectedDirectorFirst = "firstName";
            string expectedDirectorLast = "lastName";
            string expectedTitle = "title";
            wchar_t* message = L"movie title wasn't set correctly";
            Assert::AreEqual(expectedTitle, myMovie.getTitle(), message, LINE_INFO());
        }
        _CrtMemCheckpoint(&s2);
        wchar_t* leakMessage = L"there is a leak";
        bool isThereALeak = _CrtMemDifference(&s3, &s1, &s2);
        Assert::IsFalse(isThereALeak, leakMessage, LINE_INFO());
    }

第二次单元测试如下:

TEST_METHOD(constructingMovieWithParametersHeap)
    {
        _CrtMemState s1, s2, s3;
        _CrtMemCheckpoint(&s1);
        {
            Movie* myMovie = new Movie("firstName", "lastName", "title");
            string expectedDirectorFirst = "firstName";
            string expectedDirectorLast = "lastName";
            string expectedTitle = "title";
            wchar_t* message = L"movie title wasn't set correctly";
            Assert::AreEqual(expectedTitle, myMovie->getTitle(), message, LINE_INFO());
            delete myMovie;
        }
        _CrtMemCheckpoint(&s2);
        wchar_t* leakMessage = L"there is a leak";
        bool isThereALeak = _CrtMemDifference(&s3, &s1, &s2);
        Assert::IsFalse(isThereALeak, leakMessage, LINE_INFO());
    }

这是电影类:

#include "Movie.h"
using namespace std;
Movie::Movie()
{
    this->director = new Person();
    this->title = "";
    this->mediaType = 'D';    // for DVD
}
Movie::Movie(string firstName, string lastName, string title)
{
    this->director = new Person();
    this->director->setFirstName(firstName);
    this->director->setLastName(lastName);
    this->title = title;
    this->mediaType = 'D';    // for DVD
}
Movie::~Movie()
{
    delete director;
}
string Movie::getTitle()
{
    return title;
}
Movie myMovie = Movie("firstName", "lastName", "title");
// Why is the destructor is called here???

这里创建了一个临时对象,用于复制初始化myMovie,然后对该临时对象进行销毁。

你是说吗

Movie myMovie("firstName", "lastName", "title");