2012-01-29 1 views
11

지나가는 "사용 안 함"복사 및 개인 복사 생성자와 할당 연산자를 정의하여 내 개체에 할당 :는 할당을 불허하고 내가 할 수있어 이해하는 바로는 값

class MyClass 
{ 
private: 
    MyClass(const MyClass& srcMyClass); 
    MyClass& operator=(const MyClass& srcMyClass); 
} 

그러나 이것의 사용은 무엇을?
나쁜 습관이라고 생각합니까?

이런 식으로 할당 및 복사 생성자를 "비활성화"하는 것이 타당하고/유용 할 수있는 상황을 설명 할 수 있으면 감사하겠습니다.

+1

싱글 톤이 하나의 예입니다. –

답변

11

개체를 복사하는 것이 의미가 없을 때 유용합니다. 확실히 나쁜 습관으로 간주되지 않습니다.

예를 들어 네트워크 연결을 나타내는 클래스가있는 경우 해당 개체를 복사하는 것은 의미가 없습니다. 멀티 플레이어 게임에서 한 플레이어를 나타내는 클래스가 있다면 클래스를 복사 할 수 없게 할 수도 있습니다. 이 두 클래스는 실제 세계에서 복사 할 수 없거나 복사 할 수없는 것을 나타냅니다 (사람, 연결).

또한 싱글 톤을 구현하려는 경우 개체를 복사 할 수 없게 만드는 것이 표준 절차입니다.

+0

감사합니다. 할당 연산자는 어떻습니까? – LihO

+3

@ LihO 일반적으로 하나를 비활성화하면 다른 하나는 비활성화됩니다. 대입 연산자를 사용하지 않으면 다음과 같이 할 수 있습니다 :'MyClass a, b; a = b;'복사 생성자를 사용하지 않으면'MyClass b; MyClass a (b);'두 가지를 모두 비활성화하지 않으면 다른 하나를 사용할 수 없게됩니다. –

+0

그래, 이제 알았다. – LihO

0

싱글 톤 패턴을 구현하려고 할 때 개인 생성자를 사용하는 것이 완벽하게 허용됩니다. 내부 생성자와 다른 곳에서 인스턴스화 될 수 있기 때문입니다. 일단 호출되면 생성자를 취소 할 수 없습니다. 따라서 생성자는 싱글 톤 조건이 만족되는지 확인한 후에 만 ​​호출됩니다.

2

꽤 일반적인 관행입니다. 복사가 적절하지 않은 사례가 많이 있습니다.

개체가 열려있는 서버 측 소켓 (수신 네트워크 연결)을 나타냅니다. 그 객체의 복사본을 만드는 의미는 무엇입니까?

5

일반적으로 리소스를 관리하는 모든 클래스는 복사 할 수 없거나 특수한 복사 의미 체계가 있어야합니다. 그 반대의 경우도 마찬가지입니다. 복사 할 수 없거나 특수화 된 복사 의미 체계가 필요한 클래스는 자원을 관리합니다. 실제로 C++ 링구아에서 "리소스 관리"란 메모리, 네트워크 또는 데이터베이스 연결, 파일 핸들 또는 트랜잭션 실행 취소 등을 담당합니다.

리소스 관리는 많은 예제를 캡처합니다. 이것들은 접두어 연산, 접미어 연산 및 그 사이의 어떤 동작을 취하는 책임입니다. 예를 들어, 메모리 관리는 우리가 관리 할 메모리 주소에 대한 핸들을 획득하고, 아마도 그 메모리로 엉망으로 처리하고, 마지막으로 핸들을 해제하는 작업을 포함합니다.

template<typename T> 
struct memory { 
    memory(T const& val = T()) : p(new T(val)) { } 
    ~memory() { delete p } 
    T& operator*() const { return *p; } 
private: 
    T* p; 
}; 

// ... 
{ 
    memory<int> m0; 
    *m0 = 3; 
    std::cout << *m0 << '\n'; 
} 

memory 클래스는 거의 정확 : 자동 예외가 그것의 자원을 인수 한 후 약간의 시간을 전파하더라도 출시 자동으로 기본 메모리 공간을 취득합니다. 하지만 다음과 같은 시나리오를 생각해 봅시다 : 우리가 memory에 대한 전문 복사 의미를 제공하지 않았기 때문에

{ 
    memory<double> m1(3.14); 
    memory<double> m2(m1); // m2.p == m1.p (do you hear the bomb ticking?) 
} 

컴파일러는 자신의 복사 생성자를 제공하고 할당을 복사합니다. 이들은 으로 잘못 처리합니다 : m2 = m1m2.p = m1.p을 의미하므로 두 개의 포인터가 같은 주소를 가리 킵니다.그것은 잘못된 것입니다 왜냐하면 m2이 범위를 벗어나서 좋은 책임있는 객체처럼 리소스를 해제하고 m1이 범위를 벗어나서 리소스를 해제하면 동일한 리소스 m2이 이미 해제되어 이중 삭제를 완료했기 때문에 잘못되었습니다 - 악명 높은 정의되지 않은 동작 시나리오. 또한 C++에서는 주목할 필요없이 객체의 복사본을 만드는 것이 매우 쉽습니다. 즉, 값으로 매개 변수를 가져 오거나 값으로 매개 변수를 반환하거나 참조로 매개 변수를 가져 오는 함수를 호출 한 다음 해당 함수를 가져 오거나 반환하는 다른 함수를 호출하는 함수입니다. 가치에 의한 매개 변수 ... 그것은 단지 일이라고 가정하는 것이 더 쉽습니다.

이 모든 것은 클래스 '존재 이유'가 리소스를 관리 할 때 즉시 복사를 처리해야한다는 것을 알아야한다는 것을 말합니다. 당신은 당신이 무엇을 의미하는지 복사를 결정하는 반면 당신은, 복사를 지원

  • 결정해야한다 : 자원의 안전한 공유를 더 공유가 전혀 없다 그래서 기본 자원의 깊은 복사를 수행하거나 copy-on-write에서와 같이 두 가지 방법을 결합 또는 게으른 사본. 어떤 경로를 선택하든 특수 복사 생성자 사본 지정 연산자를 제공해야합니다.
  • 또는 자원 복사를 지원하지 않으므로 복사 생성자 및 복사 할당 연산자를 비활성화 할 수 있습니다.

나는 자원 관리가 복사를 비활성화하거나 특수 복사 의미를 제공하는 유일한 경우라고 말합니다. 이는 The Rule of Three에 대한 또 다른 관점입니다.

0

싱글 톤의 경우처럼 개인용 생성자가 필요한지 확인한 후에 만 ​​객체 인스턴스를 생성 할 수있는 경우. 생성자가 호출되면 객체 인스턴스가 호출되고 이미 다른 인스턴스가 있는지 확인하는 데 아무런 문제가 없습니다. 그래서 우리는 메인 클래스의 멤버 함수를 호출하고 멤버 함수 내부에서 다른 인스턴스가 이미 메모리에 있는지 확인합니다. 생성자가 호출되지 않으면 호출됩니다. 그렇지 않으면 중단되었습니다. 개체의 데이터를 안전하게 보관해야하며 복사를 허용해서는 안되는 단일 클래스 또는 기타 보호 된 클래스를 확인하십시오.

도 확인하십시오. Singleton Class in C++

관련 문제