문제

클래스 생성자 내에서 "this"를 포인터로 전달하고 생성자가 반환되기 전에 객체의 멤버를 가리키는 데 사용 할 수 있습니까?

액세스 된 멤버가 함수 호출 전에 올바르게 초기화되는 한이 작업을 수행하는 것이 안전합니까?

예로서:

#include <iostream>

class Stuff
{
public:
    static void print_number(void *param)
    {
        std::cout << reinterpret_cast<Stuff*>(param)->number;
    }

    int number;

    Stuff(int number_)
        : number(number_)
    {
        print_number(this);
    }
};

void main() {
    Stuff stuff(12345);
}

나는 이것이 효과가 없다고 생각했지만 그럴 것 같습니다. 이 표준 행동입니까, 아니면 정의되지 않은 행동입니까?

도움이 되었습니까?

해결책

C ++의 객체를 인스턴스화하면 생성자의 코드가 마지막으로 실행 된 것입니다. 슈퍼 클래스 초기화, 슈퍼 클래스 생성자 실행 및 메모리 할당을 포함한 기타 모든 초기화는 미리 발생합니다. 생성자의 코드는 객체가 구성되면 실제로 추가 초기화를 수행하는 것입니다. 따라서 클래스에서 "이"포인터를 사용하는 것이 완벽하게 유효하며 완전히 구성된 물체를 가리킨다고 가정합니다.

물론, 생성자 코드에서 아직 초기화되지 않은 경우, 비 초기의 멤버 변수를 조심해야합니다.

다른 팁

이것에 대한 좋은 답변을 찾을 수 있습니다 여기 (C ++ FAQ).

상속 된 모든 멤버와 호출 클래스의 구성원은 생성자의 코드 실행이 시작될 때 구성되었으므로 안전하게 참조 할 수 있습니다.

메인 gotcha는 가상 함수를 호출해서는 안된다는 것입니다. this. 대부분의 경우 나는 이것을 시도했지만 기본 클래스의 기능이라고 부르지 만 표준은 결과가 정의되지 않았다고 생각합니다.

제시된 코드의 부수적 인 코드로서 대신에 void*:

class Stuff
{
public:
    template <typename T>
    static void print_number(const T& t)
    {
        std::cout << t.number;
    }

    int number;

    Stuff(int number_)
    : number(number_)
    {
        print_number(*this);
    }
};

그런 다음 유형의 경우 컴파일 오류가 발생합니다. t A가 없습니다 number 회원.

앤디, 나는 당신이 표준의 정의되지 않은 부분에 대해 틀렸다고 생각합니다.

생성자에있을 때 "이것은"유형이 기본 클래스 생성하는 객체의 경우 기본 클래스에서 부분적으로 구현 된 가상 함수가 호출되고 가상 테이블의 포인터가 따르지 않음을 의미합니다.

더 많은 정보 C ++ FAQ 라이트...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top