2016-08-25 17 views
0

데이터베이스 클래스가 있고 명시 적 생성자가 전달 된 플래그를 기반으로 데이터베이스에 연결을 시도합니다. 실패하면 전달됩니다. 이것은 바람직하지 않습니다 (데이터베이스가 다른 응용 프로그램에서 생성되지 않았을 수 있습니다). 그래서 빈 생성자와 기본 이동 생성자를 추가했습니다. 유틸리티 클래스에서 나는 데이터베이스가 생성 될 때까지 기다린다.기본 이동 생성자

유닛 테스트에서 이동하기 전에 database_utils::connected()은 false를 반환하고 이동 후에는 true를 반환한다. 그러나 데이터베이스를 사용하는 함수를 호출하면 library routine called out of sequence 오류가 발생합니다. 이것은 데이터베이스 또는 잘못된 형식의 select 문을 열지 않았 음을 의미하지만 생성자와 소멸자는 올바른 순서로 호출되며 데이터베이스를 생성하고 데이터베이스를 채우고 select 문이 작동하는 데이터베이스 자체에 대한 단위 테스트가 있습니다.

내 질문 : 기본 이동 실제로 이동 여부 아닌가요? 기대되는 행동을 얻기 위해 내가해야 할 일이 없다면?

샘플 코드 :

class database 
{ 
    database() : connected_(false), database_(nullptr) { } 
    database(/* params */) : connected_(false), database_(nullptr) { 
     /* attempt connection, throw on fail */ 
     connected_ = true; 
    } 
    database(database& other) = default; 
    database(database&& other) = default; 
    database& operator=(database&& other) = default; 
    ~database() { /* clean up */ } 
    operator bool() const { return connected_; } 

    bool connected_; 
    sqlite3* database_; 
}; 

class database_utils 
{ 
    database_utils() : db_() { } 
    void connect() { 
     db_ = std::move(database(/*params*/)); 
    } 
    bool connected() { return db_; } 
    void example_select(/* params */) { 
     /* use db_ */ 
    } 
    database db_; 
}; 
+0

이동 생성자가 호출되는지 확인하려면 디버깅 문을 넣고 실행되는지 확인하십시오. 물론 기본 생성자에는 'database_'와 같이 move-from 객체의 포인터를 null로 만들지 않을 것이므로 확실히 버그와 비슷합니다. 당신은 옳은 일을하는 자신 만의 생성자를 작성해야합니다. –

+0

[OT] : 복사 생성자가 const 참조로 인수를받습니다. – Jarod42

+1

아마도 두 번 클린업을 피하기 위해 move 생성자가 이동 된 포인터를 재설정하기를 원할 것입니다. – Jarod42

답변

2

기본 이동 생성자는 모든 이동 않습니다.

그러나 database_은 포인터입니다. 포인터 이동은 실제로 복사입니다.

그러면 소멸자에서 database_이 삭제됩니다.

database_이 동일한 메모리 위치를 가리키고 있기 때문에 database_이 하이퍼 스페이스를 가리 키기 때문에 "새로운"객체는 안정되지 않은 상태가됩니다.

database_을 스마트 포인터로 변경하면 기본 이동 생성자가 올바르게 작동합니다.

또는 모든 것을 이동하는 이동 생성자를 만들고 및 connected_에서 false으로 설정하십시오.

+0

나는 포인터 이동이 스왑 일 것이라고 생각 했으므로 a-> 0x0000과 b-> 0x1234가 a-> 0x1234가되고 b-> 0x0000이된다. –

+0

아니요, 올바르지 않습니다. 자신의 이동 생성자를 수행하는 경우 스왑은 좋지만 기본 이동 생성자는 스왑을 수행하지 않습니다. – Nick