【问题标题】:C++ Why is the destructor immediately called after the object has been constructed in the stack?C++为什么在堆栈中构造对象后立即调用析构函数?
【发布时间】:2016-03-02 19:23:28
【问题描述】:

我有两个单元测试。在第一个中,我在堆栈中创建对象 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;
}

【问题讨论】:

  • @Leeor:嗨!欢迎来到评论区。这是给 cmets 的。当您想向问题作者请求更多信息以帮助您回答问题时,您可以编写 cmets。当您准备好为问题提供解决方案时,您可以编写一个答案。答案部分在下面:↓↓↓↓↓↓↓↓ 谢谢,祝您有美好的一天!
  • @LightnessRacesinOrbit,伙计,这种语气没有理由。当我写评论时,还没有答案,我认为关于基本概念的问题可以通过简单的“查找主题 X”评论来回答,特别是因为它肯定已经被问了几十次了。
  • @Leeor:什么“语气”?我特意对你好。只是没有取悦一些人。 叹息

标签: c++ destructor heap-memory stack-memory


【解决方案1】:
Movie myMovie = Movie("firstName", "lastName", "title");
// Why is the destructor is called here???

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

你是说

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

【讨论】:

  • 如果原始代码导致访问冲突,则强烈表明 Movie 中的复制语义被严重破坏。
猜你喜欢
  • 2014-09-18
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
  • 2013-04-14
  • 2010-11-24
  • 1970-01-01
  • 2016-02-24
  • 2014-04-22
相关资源
最近更新 更多