문제

C ++ 11은 컴파일러를 기본 구현을 만듭니다 어떤 것도 특별 회원 기능. 함수를 삭제하는 값을 볼 수 있지만 함수를 명시 적으로 기본값으로 표시하는 값은 어디에 있습니까? 공허하게두면 컴파일러가 어쨌든 할 것입니다.

내가 볼 수있는 유일한 점은 기본 생성자가 다른 생성자가 없을 때만 생성된다는 것입니다.

class eg {
public:
    eg(int i);
    eg() = default; 
};

그러나 지금 당신이 지금하는 방식보다 정말 낫습니까?

class eg {
public:
    eg(int i);
    eg() {}
};

아니면 유스 케이스를 놓치고 있습니까?

도움이 되었습니까?

해결책

기본 생성자에게는 선언이 있으며 해당 선언에는 일반 액세스 규칙이 적용됩니다. 예를 들어 기본 사본 생성자를 보호 할 수 있습니다. 이러한 새로운 선언이 없으면 기본 생성 회원이 공개됩니다.

다른 팁

그 예 Stroustrup의 웹 사이트 요점을 이해하는 데 도움이 될 수 있습니다.

기본 및 삭제 된 함수 - 기본값 제어

"복사 금지"의 일반적인 관용구는 이제 직접 표현 될 수 있습니다.

class X {
  // ...

  X& operator=(const X&) = delete;    // Disallow copying
  X(const X&) = delete;
};

반대로, 우리는 또한 기본적으로 사본 동작을 원한다고 명시 적으로 말할 수 있습니다.

class Y {
  // ...
  Y& operator=(const Y&) = default;   // default copy semantics
  Y(const Y&) = default;

};

기본값에 대한 명시 적은 분명히 중복되지만 해당 효과에 대한 의견은 (더 나쁜) 기본 동작을 제공하기위한 사본 작업을 명시 적으로 정의하는 사용자는 드문 일이 아닙니다. 기본 동작을 구현하기 위해 컴파일러에 맡기는 것은 더 간단하고 오류가 적고 종종 더 나은 객체 코드로 이어집니다. "기본"메커니즘은 기본값이있는 모든 기능에 사용할 수 있습니다. "삭제"메커니즘은 모든 기능에 사용할 수 있습니다. 예를 들어, 우리는 다음과 같은 바람직하지 않은 변환을 제거 할 수 있습니다.

struct Z {
  // ...

  Z(long long);     // can initialize with an long long
  Z(long) = delete; // but not anything less
};

생성 된 기능의 접근성 (개인/보호)을 변경할뿐만 아니라 가상으로 만들 수 있습니다.

struct S
{
    virtual ~S();
    virtual S& operator=(const S&);
};

S::~S() = default;
S& S::operator=(const S&) = default;

기본 함수의 다음 측면을 수정할 수 있습니다.

  • 액세스 (비공개 비공개)
  • 가상
  • 명시 적 (생성자)
  • 예외 사양
  • 매개 변수의 구성

그러나 그렇게하려면 기능은 클래스 외부에서 정의되어야합니다 (8.4.2/2 C ++ 0X 최종위원회 초안).

Lawrence Crowl의 원본 제안 버전은 다음과 같습니다. 여기.

감사합니다 로저 페이트 설명과 인용을 위해.

1) 암시 적으로 생성 된 파괴자는 현재 가상이 아닙니다. 따라서 가상으로 만들려면 그것들을 정의해야합니다.이 경우 효율적이지 않습니다. = 기본값으로, 당신은 암시 적으로 생성 된 파괴자로 가상과 효율성을 갖게됩니다.

2) 암시 적으로 생성 된 것과는 달리 액세스 지정자가 있습니다.

3) 기본 생성자를 인화하면 클래스는 여전히 사소한 상태로 유지됩니다.

다음은이 새로운 기능을 자세히 설명하는 기사입니다.

기본적으로 사본 생성자를 생성 할 수 있다는 것이 실제로 유용 할 것입니다. 기본 생성자를 생성하는 데 사용되는 것을 볼 수 없습니다. 기본 생성자를 생성하는 데 사용됩니다.

Scott Meyer 's Great Book의 항목 17 참조 "효과적인 현대 C ++". 기본 카피 생성자, 복사 작업 및 이동 작업이 생성되거나 생성되지 않은 많은 조건을 설명합니다.

다시 말해, 컴파일러는 "어쨌든 그렇게하지 않을 수 있습니다". 그러나 기본 구성 멤버 함수가 의미가있는 경우 사용자는 "기본값"키워드를 사용하여 컴파일러에 명시 적으로 생성되지 않은 기본 기능을 생성 할 수 있습니다.

항목 17의 끝에서 기억해야 할 것들에서 :

  • 이동 작업은 명시 적으로 선언 된 이동 작업, 복사 작업 또는 소멸자가없는 클래스에 대해서만 생성됩니다.

  • 카피 생성자는 명시 적으로 선언 된 사본 생성자가없는 클래스에 대해서만 생성되며 이동 작업이 선언 된 경우 삭제됩니다. 사본 할당 연산자는 명시 적으로 선언 된 사본 할당 연산자가없는 클래스에 대해서만 생성되며 이동 작업이 선언 된 경우 삭제됩니다. 명시 적으로 선언 된 파괴자가있는 클래스에서 사본 작업의 생성은 더 이상 사용되지 않습니다.

나에게 유용한 비활성화 기능, 현재 생성하는 대부분의 클래스에서는 복사 및 할당을 비활성화합니다. 컴파일러가 링커 오류에 의존하지 않고이 작업을 수행하는 기능을 갖는 것이 좋습니다.

많은 속성이있는 클래스가있는 경우 기본값은 카피 구성 자에게 더 유용합니다. 예를 들어,이 수업이있는 경우 :

class MyClass {
private:
   int offset;
   std::string name;
   std::vector<Person*> relatives;
   float weight;
   MyClass* spouse;
   Vehicle* car;
   double houseArea;
   Date birth;
   Person* parents[2];

public:
   /* Default constructor will be defined here */
};

이 방법으로 카피 건설자를 정의하는 대신 :

MyClass(const MyClass& that) :
   offset(that.offset),
   name(that.name),
   relatives(that.relatives),
   weight(that.weight),
   spouse(that.spouse),
   car(that.car),
   houseArea(that.houseArea),
   birth(that.birth),
   parents(that.parents)
{}

이 방법을 정의 할 것입니다.

MyClass(const MyClass&) = default;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top