2013-04-15 2 views
5

클래스에 기본 생성자가 없으므로 내부 변수가 항상 초기화되어야하므로 이동 생성자가 없어야합니다.기본 생성자로 인해 생성자가 생성되지 않습니다.

class Example final { 
public: 
    explicit Example(const std::string& string) : string_(
    string.empty() ? throw std::invalid_argument("string is empty") : string) {} 
    Example(const Example& other) : string_(other.string_) {} 
private: 
    Example() = delete; 
    Example(Example&& other) = delete; 
    Example& operator=(const Example& rhs) = delete; 
    Example& operator=(Example&& rhs) = delete; 
    const std::string string_; 
}; 

이 클래스는 항상 내부 문자열이 비어 있지 않은 문자열로 설정하고 내부 문자열이 Example 객체 사이에 복사됩니다 기대하고있다. 예제가 옮겨지면 std::move 호출을 통해 문자열을 비워 두어야하기 때문에 move 생성자가 여기에 적용되지 않는다는 것을 수정 했습니까?

+0

음, * clients *가 비공개 (* "default"*) 객체를 생성 할 수없는 한 * 왜 * (* 라이브러리 자체)는 그렇게 할 수 없습니까? 물론 클라이언트가 직접 생성 할 수없는 한 기본 객체가 돌아 다니는 데 문제가 없습니다. 그리고 일반적으로 클라이언트는 어쨌든 객체로부터 옮겨진 것에 대해 아무 것도 가정하지 말아야합니다 (파괴 불가능하고 아마도 할당 가능하다는 점을 제외하고). 그들은 일부 (숨겨진) 기본 상태에 있다는 것을 모릅니다. –

+0

짐작할 수 있겠지만, 이것은 내가 얻는 것입니다. 객체를 옮기고 나면 어떤 상태에 있어야합니까? 나는 그것이 '유효한'상태, 예를 들어 매달려있는 포인터가 아니어야한다는 것을 읽었지만'move' 생성자가'move_object == Object()'와 같이 객체를 디폴트 상태로 두도록 구현했습니다. –

답변

6

클래스에 기본 생성자가 없으므로 항상 내부 변수를 초기화해야하므로 클래스에 이동 생성자가 없어야한다는 내용을 따르시겠습니까?

아니요, 나는 그렇게 말하지 않습니다..

Example 개체에서 이동하여 빈 문자열로 남기는 사실은 여기에서 문제가되지 않아야합니다. 일반적으로 클라이언트는 이동 된 개체의 상태에 대해 어떤 가정도해서는 안되기 때문입니다. 그것은 합법적입니다.

이는 클라이언트가 Example 입력 상태에 대한 사전 조건이없는 함수 만 호출 할 수 있다는 것을 의미합니다. 일반적으로 의 멤버 함수 중Example의 객체 상태에 대한 사전 조건을 가지므로 (예 : string_은 null이 아니어야 함) 이 아니며 모두 정확히이 아닙니다.

예를 들어, Example의 소멸자는 string_이 비어 있는지 신경 쓰지 않아도됩니다. 그런 경우에도 작업을 수행 할 수없는 이유는 무엇입니까? 대입 연산자는 다른 일반적인 예입니다. 왜 새 문자열을 string_?에 할당 할 수 있습니까?

이보기에서 Example 개체를 빈 문자열로 남겨 두는 것은 OK입니다. 왜냐하면 모든 클라이언트가 이동 된 개체로 수행 할 수 있기 때문에 기본적으로 다시 할당하거나 파기해야합니다. 이러한 사용 사례의 경우 string_이 비어 있는지 여부는 중요하지 않습니다.

따라서 이동 생성자와 이동 할당 연산자가있는 이됩니다.

+0

그것은 정말로 그가 정의한 것을 객체의 '유효한'상태로 정의합니다. 클래스 invariant를 위반하는 move 생성자를 가지는 것은 좋지 않습니다. 그래서 문자열이 비어 있지 않은 invariant로 문서화한다면, 그는 그것을 위반하는 이동 생성자를 가져서는 안됩니다. 그러나 이것은 이동 생성자를 가질 수 없다는 것을 의미하는 것이 아니라, 필요할 때 더미 문자열 값을 사용하여 불변성을 유지해야한다는 것을 의미합니다. – bames53

+0

답변 주셔서 감사합니다[email protected] bames53, 당신은 마음 속에 가지고있는 클래스가 빈 문자열을 가져서는 안된다는 점에서 옳다. 왜냐하면 그것은 무언가에 '경로'를 전달하는 데 사용되기 때문이다. 'Example'이 항상 'string_'이 유효한 '경로'임을 보장한다면 유효한 입력 문자열이 필요 없기 때문에 여러 곳에서 훨씬 더 간단 해집니다. 그러나, 나는'move' 생성자를 구현하고'string_'을 빈 상태로두고 유효성 검사에서 그 하나의 조건만을 검사 할 수 있다고 생각합니다. 내가 염두에두고있는 클래스는'constexpr'을 사용하여 상수 문자열의 유효성 검사를 실제로합니다. –

관련 문제