2011-12-19 8 views
2

개발자가 명시 적으로 선언 한 destructorconstructor이없는 클래스의 경우를 고려하십시오. 이 경우에는 은 implicitly declared입니다. 그렇다면 클래스의 객체가 파괴 될 때만 destructorimplicitly defined이라는 사실입니까?암시 적으로 정의 된 클래스의 소멸자

생성자의 동작 또한 위와 같습니다. 클래스의 객체가 만들어 질 때만 implicitly defined입니까?

위의 코드에서 편집

class A { 
    public: 

}; 
int main() { 

} 

는 ~ (A)는() 암시 적으로 선언됩니다. 내 질문은 사실 소멸자에 대한 정의는 클래스의 객체가

class A { 
     public: 

    }; 
    int main() { 
     A a; 
    } 

처럼 인스턴스화 경우에만, 암시 적으로 이루어집니다 아니면 암시 적 객체 인스턴스화가 완료되지 않은 경우에도, 정의되어 있는지 여부?

+0

왜 이것이 적절한 지 설명하면 더 나은 답변을 줄 수 있습니다. –

+0

당신은'암묵적으로 선언 '과'암시 적으로 정의'사이에 어떤 종류의 구별을하고 있습니까? 질문을 이해하기 위해 정말로 애 쓰고 있습니다. – NPE

+0

나는 명확성을 위해 몇 가지 코드 스 니펫을 추가했습니다. –

답변

5

예, 암시 적으로 선언 된 기본 생성자 및 소멸자는 개체 인스턴스를 만들거나 파괴 할 때 암시 적으로 정의됩니다.표준 단어 (C++ 11)에서 :

12.1/6 : 디폴트 삭제 정의되지 컨스트럭터 암시가 ODR-사용될 때 정의 (3.2)는이 만드는 그 클래스 형의 객체 (1.8) 또는 최초의 선언 후에 명시 적으로 디폴트가 될 때

12.4/5 : odr-used (3.2)에서 이 클래스 유형의 객체 (3.7)를 삭제하거나 해당 객체의 명시 적으로 기본값 뒤에있을 때 기본적으로 삭제 된 것으로 정의되지 않은 소멸자가 암시 적으로 정의됩니다. 첫 번째 선언.

두 번째 코드 조각에 정의되어 있으므로 A 유형의 객체를 생성 및 소멸하지만 첫 번째 코드는 그렇지 않습니다.

+0

완벽한 답변. 감사 –

0

반면에, 사소한 프로그램 *에서 오브젝트가 생성/파괴되었는지 여부를 결정하는 것은 불가능하지만, 관찰 가능한 행동이 남아있는 한 실제로는 문제가되지 않습니다. 같은.

그러나 defined when object created/destroyeddefined if needed 사이에는가는 선이 있습니다. 아래 예제에서는 Foo::Foo()을 정의해야 할 필요가 있기 때문에 정의해야합니다. 그러나 객체가 만들어 질 때 객체가 정의되었는지 여부와 객체가 결정될 수 없는지 여부를 묻습니다.


*

함수가 정의되는지 여부
class Foo {}; 
int main(int argc, char *argv[]) { 
    if (argc>1) Foo(); // <- impossible to decide if ever constructed/destroyed 
} 

// On the other hand, compiler might be smart enough to observe that 
// Foo does not have any visible behaviour, remove Foo entirely, and in 
// effect spit out this: 
int main() {} 
+0

프로그램이 객체를 생성하거나 소멸시키는 코드를 포함해야하는지 여부를 결정할 수 있습니다 (예를 들어 명확하게 설명). 이것이 암시 적 생성자 또는 소멸자가 정의되는지 여부를 결정합니다. –

+0

@Mike Seymour : 물론 당신은 맞습니다.하지만 OP는 기본적으로'필요한 경우 정의됩니까? '라고 물어 보지 않고'객체가 생성 될 때 정의됩니다'(나는 더 명확하게하기 위해 내 포스트를 업데이트했습니다). –

0

런타임에 결정되는 것이 아니기 때문에, 소멸자 정의에만 개체 [...] 대해 인 "될 수 없다 파괴 될 것임 "단순히 실행 파일이 정적이며 특정 실행에 대해 생성되지 않았기 때문에 단순히" "입니다. 당신의 소멸자에는 호출이 최종 실행 파일에 존재하지 않는 경우

그러나, 링커 는 완전히 기능을 제거합니다하기로 결정했습니다. 더 B::B()없이 B::~B() 적 합성되지 않기 때문에 혹시이 실제로 컴파일 B를 초기화하지 않고 링크 않을 경우

class A { 
    A() {} 
    ~A() {} 
}; 
class B { 
    A a; // cannot access dtor nor ctor of A 
}; 

: 마지막 지점에 대한


은,이 예제를 고려하십시오. 그러나 B의 객체를 만들려고하면 컴파일러에서 화려한 이름을 사용합니다. 간단히 말해서 B::B()B::~B()을 합성 할 수 없기 때문입니다.

+0

소멸자에 대한 호출이 없다면, 컴파일러는 소멸자를 전혀 정의하지 않을 것입니다. 왜냐하면 그것이 표준에서 말하는 것이기 때문입니다. 그리고 당신의 모범은 운에 의해서만 작동하는 것이 아닙니다. 'B'가 인스턴스화되지 않으면 생성자가 정의되지 않기 때문에 작동합니다. –

+0

@MikeSeymour : 컴파일러는 어떻게 알 수 있습니까? 호출은 다른 컴파일 단위에서 만들 수 있습니까? – bitmask

+0

인라인 함수를 처리하는 것과 같은 방법입니다. 생성자/소멸자는 필요로하는 모든 번역 단위에서 정의되며 중복은 필요한 경우 링커에 의해 정렬됩니다. –

관련 문제