2014-08-29 1 views
5

기본 클래스에 알려진 상태 부분을 재설정하기 위해 기본 클래스 객체를 파괴하고 구성하는 것이 합법적입니까?명시 적으로 기본 클래스 소멸자/생성자를 호출하는 것이 합법적입니까?

class C : public BaseClass {...}; 

C c; 
c.BaseClass::~BaseClass(); 
new (static_cast<BaseClass*>(&c)) BaseClass; 

분명히 우리가 클래스의 소스 코드에 액세스 할 수 있다면이 효과를 얻을 수있는 다른 방법이 있습니다. 그러나 이것이 유효하지 않은 특별한 이유가있는 경우 언어 관점에서 알고 싶습니다.

+0

아니요. 시작하려면 '& c'가 기본 클래스 하위 개체의 주소와 동일하다는 보장이 없습니다. –

+0

공정한 포인트. 나는 캐스트를 추가했다. –

+0

기본 클래스에서'reconstruct' 메소드를 사용 하시겠습니까? 이것은 X-Y 문제처럼 들립니다. – sp2danny

답변

8

아니요, 유효하지 않습니다. 객체의 기본 하위 객체를 바꿀 수 없습니다. 3.8/7

C++ 11 만 원의 객체는 타입 T의 가장 파생 된 개체 (1.8)이었고, 새로운 개체가 대부분이다

경우 객체의 저장 공간을 다시 사용할 수 있도록 지정 형식 T의 파생 개체 (즉, 기본 클래스 하위 개체가 아닌 )입니다.

대체하는 객체는 기본 클래스 하위 객체이며 대부분 파생 된 객체가 아니므로 금지됩니다.

전체 개체를 바꾸려면 (즉, ~C으로 전화 한 다음 새 C을 작성하십시오.) 합법적이지만 위험 할 수 있습니다. 생성자가 던진 경우 객체는 수명이 끝난 후 두 번째로 삭제됩니다. 그러면 정의되지 않은 동작이 발생합니다.

+0

오브젝트가 C 유형의 정지를 설명 할 수 있습니까? 개체를 바꾸거나 변경하려고하지 않고 그냥 기본 클래스 영역을 다시 초기화합니다. –

+0

@ JamesT.Huggett :'new (...) BaseClass'는'C'가 아닌'BaseClass' 타입의 객체를 생성합니다. –

+0

@MikeSeymour 그러나 기본 클래스 소멸자 만 호출되었습니다. 나는 OP가 대부분의 파생 된 객체 전체를 다시 초기화하지 않고 기본 클래스 하위 객체를 "다시 초기화"하려고한다는 것을 이해합니다. – Angew

2

소멸자가 가상 ​​일 경우에만 작동합니다. 그렇지 않으면 부분적으로 파괴 된 개체가 생깁니다 (실제로는 의견을 제시하고 싶지만 합법적이지는 않습니다). 새로운 배치가 작동해야하지만, 나는 표준에 의해 실제로 허용되지 않는다고 확신한다. (그러나 나는 제대로 작동 할 것으로 보인다.) 그리고 나는 왜 당신이 이것을 원할 것인지는 모르겠다. 왜냐하면 그 물체는 파생 된 것이기 때문에, C이지만, 건설 후에는 다시 C이 될 것이고, 단지 BaseClass 일 뿐이다.

+0

아이디어는 파생 클래스에 추가 된 필드를 건드리지 않고 기본 객체의 상태를 재설정하는 것입니다. 나는 당신이 "C가 되라"는 것이 무슨 뜻인지 잘 모르겠습니다. –

+0

가상 소멸자는 왜 관련이 있습니까? 내가 원하는 소멸자를 명시 적으로 호출하고 있습니다. –

+1

"be be C"는 (는) 사용자의 '클래스 C'를 나타냅니다. 당신이 여기서하고있는 일은 완전히 틀리며 작동하지 않을 것입니다. 'BaseClass' dtor가 가상 일 경우'C' 소멸자가 호출되고 객체는 완전히 파괴됩니다. 그러나'delete'를 호출하지 않아서 메모리가 할당 해제되지 않습니다. 그것이 가상이 아니라면, 아마'BaseClass'의 비트 만 파괴 할 것입니다,하지만 그것이 작동하는 것은 틀림 없습니다. 이 모든것 대신에,'BaseClass'에 대해 간단한'reset()'메소드를 만드십시오. –

관련 문제