IT

초기화 목록 (C ++)을 사용하여 부모의 보호 된 멤버 초기화

lottoking 2020. 7. 6. 08:08
반응형

초기화 목록 (C ++)을 사용하여 부모의 보호 된 멤버 초기화


자식 클래스 생성자의 초기화 목록을 사용하여 부모 클래스에서 protected로 선언 된 데이터 멤버를 초기화 할 수 있습니까? 나는 그것을 작동시킬 수 없다. 나는 그것을 해결할 수 있지만, 필요하지 않으면 좋을 것입니다.

일부 샘플 코드 :

class Parent
{
protected:
    std::string something;
};

class Child : public Parent
{
private:
    Child() : something("Hello, World!")
    {
    }
};

이 작업을 시도하면 컴파일러에서 "클래스 'Child'에 'something'이라는 필드가 없습니다"라고 말합니다. 이와 같은 것이 가능합니까? 그렇다면 구문은 무엇입니까?

많은 감사합니다!


설명하는 방식으로는 불가능합니다. 기본 클래스에 생성자 (보호 될 수 있음)를 추가하여 전달해야합니다. 다음과 같은 것 :

class Parent
{
protected:
    Parent( const std::string& something ) : something( something )
    {}

    std::string something;
}

class Child : public Parent
{
private:
    Child() : Parent("Hello, World!")
    {
    }
}

컴파일러가 이니셜 라이저 목록에 도달하면 파생 클래스 객체는 아직 형성되지 않습니다. 그때까지 기본 클래스 생성자는 호출되지 않았습니다. 기본 클래스 생성자가 호출 된 후에 만 something존재합니다. 따라서 문제. 기본 클래스 생성자를 명시 적으로 호출하지 않으면 컴파일러는 기본 클래스에 적합한 간단한 생성자를 생성하여이를 수행합니다. 이렇게하면 something멤버가 기본적으로 초기화됩니다.

C ++ 0x 초안에서 :

12.6.2베이스와 멤버 초기화

2 mem-initializer-id의 이름은 생성자 클래스의 범위에서 조회되며 해당 범위에서 찾을 수없는 경우 생성자의 정의가 포함 된 범위에서 조회됩니다. [참고 : 생성자의 클래스에 클래스의 직접 또는 가상 기본 클래스와 이름이 같은 멤버가 포함 된 경우 멤버 또는 기본 클래스의 이름을 지정하고 단일 식별자로 구성된 mem-initializer-id는 클래스 멤버를 나타냅니다. 숨겨진 기본 클래스의 meminitializer-id는 규정 된 이름을 사용하여 지정할 수 있습니다. —end note] mem-initializer-id가 생성자의 클래스, 생성자의 클래스의 비 정적 데이터 멤버 또는 해당 클래스의 직접 또는 가상 기반의 이름을 지정하지 않으면 mem-initializer는 잘못 구성됩니다.

참고 : 강조 광산.


당신은 할 수없는 파생 클래스 생성자 초기화 목록에서 상위 클래스의 멤버를 초기화합니다. 그들이 보호되는지, 공개인지 또는 다른 것이 중요하지 않습니다.

예제에서 member somethingParentclass의 멤버이므로 클래스의 생성자 이니셜 라이저 목록에서만 초기화 할 수 있습니다 Parent.


키워드 "using"을 사용하여 이런 식으로 시도해 볼 수 있습니다.

class Parent
{

protected:
std::string something;
};

class Child : public Parent
{

private:
using Parent::something;
Child()
{
    something="Hello, World!";
}
};

참고 URL : https://stackoverflow.com/questions/2290733/initialize-parents-protected-members-with-initialization-list-c

반응형