ProgramingTip

이 C ++를 복사 할 수 있습니까?

bestdevel 2020. 11. 19. 21:48
반응형

이 C ++를 복사 할 수 있습니까?


제목을 참조하십시오.

나는 가지고있다 :

class Foo {
   private:
     Foo();
   public:
     static Foo* create();
}

Foo를 복사 할 수 없습니까?

감사합니다!


class Foo {
   private:
     Foo();
     Foo( const Foo& ); // non construction-copyable
     Foo& operator=( const Foo& ); // non copyable
   public:
     static Foo* create();
}

boost를 사용하는 경우 복사 불가능에서 상속 할 수도 있습니다. http://www.boost.org/doc/libs/1_41_0/boost/noncopyable.hpp

편집 :이 기능을 지원하는 컴파일러가있는 경우 C ++ 11 버전 :

class Foo {
   private:
     Foo();
     Foo( const Foo& ) = delete; // non construction-copyable
     Foo& operator=( const Foo& ) = delete; // non copyable
   public:
     static Foo* create();
}

복사 생성자와 할당 연산자도 비공개로 만듭니다. 선언만으로 충분하며 구현을 제공 할 필요가 없습니다.


복사 생성이 허용되지 않는 또 다른 방법은 편의를 위해 DISALLOW_COPY_AND_ASSIGN 매크로를 사용할 수 있습니다.

// A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  TypeName(const TypeName&) = delete;      \
  void operator=(const TypeName&) = delete

그런 다음 Foo 클래스에서 :

class Foo {
 public:
  Foo(int f);
  ~Foo();

 private:
  DISALLOW_COPY_AND_ASSIGN(Foo);
};

Google 스타일 시트의 참조


#include <boost/utility.hpp>
class Foo : boost::noncopyable {...

Scott Meyers가 한때 말했듯이 ... "역시 좋은 수업입니다. 단지 이름이 약간의 비 자연스럽고 오류가 아니라고 생각합니다"또는 이와 같은 것입니다.


거기에 약간을 추가하십시오.

말했다로되어에있는 한 기존의 솔루션입니다 선언 모두 Copy ConstructorAssignment Operator같이 private하고, 하지정의 를.

  • 이므로 클래스의 개인 부분에 액세스 할 수없는 user-가이를 사용하려고 private하면 컴파일 타임 오류가 발생 합니다.
  • 어떤 잎 친구 (그리고 클래스 자체) 에러가의 형태에서 발생하는 undefined symbol에 하나, 링크시 에 대부분의 아마 (당신이 그 존재를 확인하는 경우) 또는 실행 (라이브러리를로드 할 때).

두 번째 경우에는 오류가 있고 파일 때문에 많은 경우에 표시가 없기 때문에 코드를 직접 확인해야합니다. 그것은 당신의 수업 방법과 친구들로 제한됩니다.


또한 상속 상속 및 구성 과정에서 유의할 필요가 있습니다. 컴파일러는 Default Constructor, the Copy Constructor, the Assignment OperatorDestructorif 의 기본 버전 만 생성 합니다.

즉, 네 가지 중이 하나 에 대해 클래스의 모든 기본 및 속성에 액세스 할 수있는 경우 에만 자동으로 생성 됩니다 .

// What does boost::noncopyable looks like >
class Uncopyable {
public:
  Uncopyable() {}

private:
  Uncopyable(const Uncopyable&);
  Uncopyable& operator=(const Uncopyable&);
};

그렇기 때문에이 클래스에서 상속 (또는 속성으로 사용)하면 해당 연산자를 직접 정의하지 않는 한 자신의 클래스를 복사하거나 할당 할 수 없게됩니다.

일반적으로 상속은 두 가지 이유로 구성보다 선택됩니다.

  • Uncopyable다형성이 그다지 유용하지 않더라도 객체는 효과적 입니다.
  • 상속은 EBO또는 Empty Base Optimization로 이어지지 만 속성은 주소 지정이 가능하므로 실제로 필요하지 않더라도 메모리 (클래스의 각 인스턴스에서)를 차지하지만 컴파일러는 기본 클래스에 대해이 오버 헤드를 추가하지 않을 가능성이 있습니다.

또는 연산자를 private으로 선언하고 자신의 클래스에서 정의하지 않을 수 있지만 코드는 자체 문서화 가 적고이 속성이있는 클래스를 자동으로 검색 할 수 없습니다 ( 본격적인 파서).

이것이 메커니즘에 대한 빛을 비추 길 바랍니다.


C ++ 11에서는 = delete선언 뒤에 배치하여 기본 복사 및 할당 생성자의 생성을 명시 적으로 비활성화 할 수 있습니다 .

에서 위키 백과 :

struct NonCopyable {
    NonCopyable() = default;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable & operator=(const NonCopyable&) = delete;
};

물론 수업도 마찬가지입니다.


C ++ 객체를 복사 불가능하게 만드는 일반적인 방법은 복사 생성자와 복사 할당 연산자를 명시 적으로 선언하지만 구현하지 않는 것입니다. 이것은 컴파일러가 자체적으로 생성하는 것을 방지합니다. (일반적으로 이것은 private링커 오류 대신 컴파일 오류를 생성하도록 선언하는 것과 함께 수행됩니다 .)

boost::noncopyable위에서 설명한대로 상속 할 수 있는 클래스도 있습니다.


복사 생성자를 비공개로 만듭니다.

Foo(const Foo& src);

구현할 필요가 없으며 헤더 파일에서 선언하기 만하면됩니다.


이것이 내가 사용하는 것입니다.

/* Utility classes */

struct NoCopy
{
public:
    NoCopy() {}
private:
    NoCopy(const NoCopy &);
};

struct NoAssign
{
private:
    NoAssign &operator=(const NoAssign &);
};

struct NonInstantiable
{
private:
    NonInstantiable();
};

struct NoCopyAssign : NoCopy, NoAssign
{
};
typedef NoCopyAssign NoAssignCopy;

귀하의 경우 :

struct Example : NoCopy
{
};

C ++ 11의 좋은 방법은 복사 생성자와 할당을 공개적으로 삭제 된 것으로 선언하는 것입니다. 비공개로 삭제하지 않고 공개적으로 삭제 : https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-delete

참고 URL : https://stackoverflow.com/questions/2173746/how-do-i-make-this-c-object-non-copyable

반응형