클래스를 위해 컴파일러가 만든 모든 멤버 함수는 무엇입니까? 그게 항상 일어나나요?
클래스를 위해 컴파일러가 만든 모든 멤버 함수는 무엇입니까? 그게 항상 일어나나요? 소멸자처럼. 내 관심사는 모든 클래스에 대해 생성 여부와 기본 생성자가 필요한 이유는 무엇입니까?
C ++ 98/03
필요한 경우
- 사용자가 직접 생성 할 가능성이없는 한 컴파일러는 기본 생성자 를 생성합니다 .
- 는 컴파일러 user-가 직접 선언하지 않는 한 복사 생성자 를 생성합니다 .
- 사용자가 직접 선언하지 않는 한 컴파일러는 복사 할당 연산자 를 생성합니다 .
- 컴파일러는 여러분이 선언하지 않는 한 소멸자 를 생성합니다 .
Péter가 유용한 주석에서 말했듯이 모든 것이 필요할 때만 컴파일러에 의해 생성 됩니다. (차이점은 컴파일러가 생성 할 수없는 경우 사용하지 않는 한 괜찮다는 것입니다.)
C ++ 11
C ++ 11은 C ++ 14에도 적용되는 다음 규칙을 추가합니다 (towi에 대한, 이 주석 참조 ) .
- 는 다음과 컴파일러 같은 경우
이동 생성자를 생성합니다.
- 에는 user-가 거기 선언되지 않습니다 복사 생성자 및
- 에는 user-가 거기 선언되지 않습니다 복사 할당 연산자 및
- 에는 사용자가 선언이없는 이동 할당 연산자가 와
- 사용자가 선언 한 소멸자 가 없습니다 .
- 그것은되어 있지 표시
delete
, D를 - 그리고 모든 구성원과 기지는 움직일 수 있습니다.
- 이동 할당 연산자의 생성 경우 와유사하게 다음과 같은 경우입니다.
- 에는 user-가 거기 선언되지 않습니다 복사 생성자 및
- 에는 user-가 거기 선언되지 않습니다 복사 할당 연산자 및
- user-가 선언에는이없는 이동 생성자 와
- 사용자가 선언 한 소멸자 가 없습니다 .
- 그것은되어 있지 표시
delete
, D를 - 그리고 모든 구성원과 기지는 움직일 수 있습니다.
C ++ 03 규칙보다 조금 더 정교하며 실제로 더 의미가 있습니다.
위의 내용을 더 쉽게 이해 광고주 :
class Thing {
public:
Thing(); // default constructor
Thing(const Thing&); // copy c'tor
Thing& operator=(const Thing&); // copy-assign
~Thing(); // d'tor
// C++11:
Thing(Thing&&); // move c'tor
Thing& operator=(Thing&&); // move-assign
};
더 읽을 거리 : 만약 당신이 C ++ 초보자라면 마르틴 페르난데스가 작성한 기사 에서 원래 5 가지 일명 제로의 지배 를 구현할 필요가없는 디자인을 고려해 보십시오 .
'created'에 의해 'defined'를 의미합니까?
$ 12.1- "기본 생성자 (12.1), 복사 생성자 및 복사 할당 연산자 (12.8) 및 소멸자 (12.4)는 특수 멤버 함수입니다.
'생성됨'이 '정의 됨'을 의미하는 경우 다음은 C ++ 표준의 중요한 부분입니다.
-클래스에 대해 암시 적으로 선언 된 기본 생성자는 클래스 유형 (1.8)의 개체를 만드는 데 적용 할 때 암시 적으로 정의됩니다.
-클래스에 사용자가 선언 한 소멸자가없는 경우 소멸자는 암시 적으로 선언됩니다. 암시 적으로 선언 된 소멸자는 클래스 유형의 개체를 소멸하는 데 때 암시 적으로 정의됩니다.
-클래스 정의가 복사 생성 암시 명시 적으로 선언되지 않습니다. 암시 적으로 선언 된 복사 생성자는 해당 클래스 형식의 개체 또는 해당 클래스 형식에서 파생 된 클래스 형식의 복사본에서 해당 클래스 형식의 개체를 사용하는 경우 암시 적으로 정의됩니다.
-클래스 정의가 할당 연산자를 명시 적으로 선언하지 암시 적으로 선언됩니다. 암시 적으로 선언 된 복사 할당 연산자는 해당 클래스 유형의 객체에 해당 클래스 유형의 값 또는 해당 클래스 유형에서 파생 된 클래스 유형의 값이 할당 될 때 암시 적으로 정의됩니다.
기본적으로 사용자가 구현하지 않은 경우 컴파일러는 일부 멤버 함수를 클래스에 추가합니다. 문의를 빅 4라고합니다.
- 기본 생성자
- 복사 생성자
- 복사 연산자 (할당)
- 폐물 소각로
멤버 유형 및 생성 멤버 함수에 따라 사용자가 직접 제공하는 멤버 기능이 없습니다.
C ++ 17 N4659 표준 초안
https://github.com/cplusplus/draft/blob/master/papers/n4659.pdf 6.1 "선언 및 정의"에는 모두를 요약하는 메모가 있습니다.
3 [참고 생성 : 일부 상황에서 C ++ 구현은 기본 생성자 (15.1), 복사 생성자 (15.8), 이동 할당 연산자 (15.8), 복사 할당 연산자 (15.8), 이동 할당 연산자 (15.8) 또는 소멸자 (15.4) 멤버 함수 . — end note] [예 : 주어진
#include <string> struct C { std::string s; // std::string is the standard library class (Clause 24) }; int main() { C a; C b = a; b = a; }
구현은 C의 정의를 다음과 동일하게 만드는 함수를 암시 적으로 정의합니다.
struct C { std::string s; C() : s() { } C(const C& x): s(x.s) { } C(C&& x): s(static_cast<std::string&&>(x.s)) { } // : s(std::move(x.s)) { } C& operator=(const C& x) { s = x.s; return *this; } C& operator=(C&& x) { s = static_cast<std::string&&>(x.s); return *this; } // { s = std::move(x.s); return *this; } ~ C() { } };
— 최종 예]
선언 된 조건은 다음에서 설명합니다. 기본 / 복사 / 이동 및 복사 / 이동 할당 연산자의 자동 생성 조건?
어떤 방법에 있는지 확인하는 방법 = default
은 다음에 설명 된대로 보는 것입니다 . "음성"은 클래스의 함수 선언 무엇을 의미합니까?
아래 예제는이를 수행하고 암시 적으로 정의 된 모든 함수를 실행합니다.
#include <cassert>
#include <string>
struct Default {
int i;
Default() = default;
Default(const Default&) = default;
Default& operator=(Default&) = default;
Default& operator=(const Default&) = default;
Default(Default&&) = default;
Default& operator=(Default&&) = default;
~Default() = default;
};
struct Instrument {
int i;
static std::string last_call;
Instrument() { last_call = "ctor"; }
Instrument(const Instrument&) { last_call = "copy ctor"; }
Instrument& operator=(Instrument&) { last_call = "copy assign"; return *this; }
Instrument& operator=(const Instrument&) { last_call = "copy assign const"; return *this; }
Instrument(Instrument&&) { last_call = "move ctor"; }
Instrument& operator=(Instrument&&) { last_call = "move assign"; return *this; }
~Instrument() { last_call = "dtor"; }
};
std::string Instrument::last_call;
int main() {
// See what the default constructors are doing.
{
// Default constructor.
Default ctor;
// i is uninitialized.
// std::cout << ctor.i << std::endl;
ctor.i = 1;
// Copy constructor.
Default copy_ctor(ctor);
assert(copy_ctor.i = 1);
// Copy assignment.
Default copy_assign;
copy_assign = ctor;
assert(copy_assign.i = 1);
// Copy assignment const.
const Default const_ctor(ctor);
Default copy_assign_const;
copy_assign_const = const_ctor;
assert(copy_assign_const.i == 1);
// Move constructor.
Default move_ctor(std::move(ctor));
assert(move_ctor.i == 1);
// Move assignment.
Default move_assign;
move_assign = std::move(ctor);
assert(move_assign.i == 1);
}
// Check that the constructors are called by these calls.
{
// Default constructor.
Instrument ctor;
assert(Instrument::last_call == "ctor");
// Copy constructor.
Instrument copy_ctor(ctor);
assert(Instrument::last_call == "copy ctor");
// Copy assignment.
copy_ctor = ctor;
assert(Instrument::last_call == "copy assign");
// Copy assignment const.
const Instrument const_ctor(ctor);
Instrument copy_assign_const;
copy_assign_const = const_ctor;
assert(Instrument::last_call == "copy assign const");
// Move constructor.
Instrument move_ctor(std::move(ctor));
assert(Instrument::last_call == "move ctor");
// Move assignment.
Instrument move_assign;
move_assign = std::move(ctor);
assert(Instrument::last_call == "move assign");
// Destructor.
{
Instrument dtor;
}
assert(Instrument::last_call == "dtor");
}
}
GCC 7.3.0으로 테스트 됨 :
g++ -std=c++11 implicitly_defined.cpp
다른 답변은 생성 된 내용을 알려 주거나 생성 할 수 있습니다.
내 관심사는 모든 클래스에 대해 생성 여부입니다.
왜 걱정합니까? 실행 파일에 원하지 않는 코드를 생성한다고 생각하십니까? 가능성은 낮지 만 환경에 따라 쉽게 확인할 수 있습니다.
아니면 당신이 원할 때 생성자를 만들지 않을 수도 있다는 우려가 있었습니까? 걱정할 필요가 없습니다. 필요한 경우 항상 생성되며 사용자가 제공하지 않습니다.
... 기본 생성자가 필요한 이유는 무엇입니까?
클래스에는 체계적으로 호출해야하는 자체 소멸자가있는 개체가 내부에있을 수 있기 때문입니다. 예를 들어, 주어진 ...
struct X
{
std::string a;
std::string b;
};
... 기본 소멸자는 a와 b의 소멸자가 실행되도록합니다.
'ProgramingTip' 카테고리의 다른 글
t-sql의 "tinyint"를 C #에서 정수로 어떻게 변환 할 수 있습니까? (0) | 2020.12.12 |
---|---|
jquery / javascript : function (e) {… e는 무엇입니까? (0) | 2020.12.12 |
파일에 vim 설정 포함 (0) | 2020.12.12 |
jar를 로컬 저장소에 게시하는 방법은 무엇입니까? (0) | 2020.12.12 |
Numpy의 평균 제곱 오차? (0) | 2020.12.11 |