2015-11-28 1 views
2

У меня есть два модульных теста. В первом я создаю объект myMovie в стеке. Объект создается, и сразу же после этого вызывается деструктор. Это приводит к сбою модульного теста, потому что, когда myMovie выпадает из области действия, деструктор вызывается снова. Это приводит к нарушению доступа.C++ Почему деструктор немедленно вызван после того, как объект был создан в стеке?

Однако, если я создаю объект в куче, все будет хорошо. Почему деструктор сразу вызван после того, как объект был создан в стеке?

Сначала один, как это:

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; 
} 
+0

@Leeor: Привет! Добро пожаловать в раздел _comment_. Это для комментариев. Вы пишете комментарии, когда хотите запросить дополнительную информацию у автора вопроса, чтобы помочь вам ответить на вопрос. Когда вы будете готовы решить проблему, напишите _answer_. Раздел ответов внизу: ↓↓↓↓↓↓↓↓ Спасибо и отлично провели день! –

+0

@LightnessRacesinOrbit, чувак, нет причин для этого тона. Когда я написал комментарий, ответа еще не было, и я думаю, что на вопросы об основополагающей концепции можно ответить простым комментарием «взглянуть на объект X», тем более, что его, должно быть, уже просили десятки раз. – Leeor

+0

@Leeor: Какой «тон»? Я ушел с дороги, чтобы быть с тобой добрым. Там просто не нравится некоторые люди. * вздох * –

ответ

6
Movie myMovie = Movie("firstName", "lastName", "title"); 
// Why is the destructor is called here??? 

здесь временный объект созданный и используемый для копирования инициализации myMovie, то временное разрушено.

вы имели в виду

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

, и если исходный код вызывает нарушение доступа, это сильный индикатор дико сломанной семантики копии в «Кино». –