2014-12-14 1 views
1

나는 코드의 follwing을 블록을 가지고 :왜 STL 벡터는 할당시 기본 생성자를 호출합니까?

#include <vector> 
#include <iostream> 

struct TestStruct { 
    bool wasCreated; 

    TestStruct() { 
     std::cout << "Default Constructor" << std::endl; 
     wasCreated = false; 
    } 

    ~TestStruct() { 
     if (wasCreated) { 
      DoImportantStuff(); 
     } 
    } 

    void Create() { 
     wasCreated = true; 
    } 

    // delete all copy stuff 
    TestStruct(const TestStruct&) = delete; 
    TestStruct& operator=(const TestStruct&) = delete; 


    // implement only move assignment & ctor 
    TestStruct(TestStruct&& other) { 
     std::swap(wasCreated, other.wasCreated); 
    } 

    TestStruct& operator=(TestStruct&& other) { 
     std::swap(wasCreated, other.wasCreated); 
     return *this; 
    } 

    // very important stuff 
    void DoImportantStuff() { 
     std::cout << "Do Important Stuff" << std::endl; 
    } 
}; 

int main() { 

    std::vector<TestStruct> testVector; 

    testVector.emplace_back(TestStruct()); 
    testVector.emplace_back(TestStruct()); 

    std::cin.get(); 
} 

이 코드는 출력에 이르게 :

기본 생성자

중요 물건

기본 생성자

할 일을 수행 중요 항목

중요 물건

가 Basicly 내가 메모리를 소유하지만 Create()를 호출 할 경우에만이 메모리를 할당 클래스를 쓰고 싶다 마십시오. 메모리 누수를 피하고 할당되지 않은 메모리를 삭제하지 않으려면 wasCreated을 도입했습니다. Create()을 호출 할 때만 적용됩니다. 모든 TestStruct는 하나의 벡터에 저장해야합니다. 따라서 구현 된 코드에서 & ctor를 실행하고 두 코드 모두를 삭제합니다 & ctor.

이제는 새로운 메모리를 할당 할 때 벡터가 내 TestStruct의 기본 생성자를 interly 호출한다고 생각합니다. 그렇다면 왜 벡터가 메모리 할당시 기본 생성자를 호출하게할까요? 내 할당자가 필요합니까?

+0

유효한 진입 점 중 하나를 사용하십시오. 'void main()'은 그들 중 하나가 아닙니다. – nvoigt

+0

** - 1 ** '보이드 메인'. 그러지 마. –

+3

@ Cheersandhth.-Alf +1 카운터. 'void main'은 더 이상 유용하지 않은 질문을하지 않습니다. – immibis

답변

3

문제는 이동 생성자가 잘못 구현 된 것입니다. 새로 생성 된 객체와 이동 된 객체간에 wasCreated을 바꿉니다. 그러나 새로 생성 된 객체 의 변수는 아직 초기화되지 않았습니다 (기본값으로 생성 된 bool은 알 수없는 값을가집니다). 따라서 TestStruct()으로 생성 된 임시 객체는 초기화되지 않은 부울을받습니다. 이는 결과적으로 true인데, 따라서 소멸자에서 DoImportantStuff()을 호출합니다.

// implement only move assignment & ctor 
TestStruct(TestStruct&& other) : wasCreated(other.wasCreated) { 
    other.wasCreated = false; 
} 

(. 당신은 더 이상, 예전 아무것도 소유하지 않은 새로 생성 된 개체에 대한 소유권을 이동 한)

하지 마십시오 :

그래서 이동 생성자는 다음과 같이 보일 것입니다 할당 연산자와 생성자를 혼동한다. 그들은 다른 일을합니다. 대입 연산자는 두 객체를 모두 처리합니다.; 생성자의 경우, 생성되는 객체는 잘 구성되어 있지 않으므로 유효한 상태가 아닙니다.

한편, emplace_back()은 사용 방법이 무의미합니다. 그것의 목적은 그것의 주장을 벡터 안에있는 객체의 생성자에 직접 전달하는 것이다.당신이 기본 생성자 (인수)를 가지고 있기 때문에, 호출은 다음과 같아야합니다

testVector.emplace_back(); 

이이 자리에 TestStruct 기본-구성합니다.

0

이제는 dontst가 새로운 메모리를 할당 할 때 내 TestStruct의 기본 생성자를 중간에서 호출하는 것으로 보입니다.

기본 생성 벡터는 크기가 0이므로 생성 할 개체가 없습니다.

벡터가 일부 개체를 기본 생성하도록하려면 크기를 조정하십시오.

+0

'testVector.resize (10);'또는'std :: vector testVector (10);'DoImportantStuff()'가 호출 될 때. – TheUnimake

관련 문제