2013-03-23 2 views
2

예를 들어, 다음과 같은 코드가 있다고 가정합니다.초기화 목록과 관련된 문제 C++

class Foo 
{ 
    public: 
    Foo(int x) : _foo(x) 
    { 

    } 

    private: 
    int _foo; 

    protected: 
    std::string _bar; 
}; 

class Bar : public Foo 
{ 
    public: 
    Bar() : Foo(10), _temp("something"), _bar("something_else") 
    { 

    } 
    private: 
    std::string _temp; 
}; 

int main() 
{ 
    Bar stool; 
} 

_bar 푸 클래스이며 그렇게 이것은 당신이 그 일을 가겠어요 어떻게하지,이 존재를 알고 나타나지 않기 때문에 코드가 실행되지 않습니다? 아니면 Foo의 생성자에 _bar가 있습니까? 이것은 작동하지만 _bar에 항상 할당 할 필요가없는 것은 무엇입니까?

편집 : 아래는 실제 사용했던 코드입니다.

Entity::Entity(GameState *state, bool collidable) 
    :_isLoaded(false), _state(state), alive(true), collidable(collidable),    name(entityDetault) 

{

}

Entity::Entity(GameState *state, bool collidable, entityName _name) 
    :_isLoaded(false), _state(state), alive(true), collidable(collidable), name(_name) 
{ 

} 

후 자식 클래스가이 생성자를 사용합니다;

Player::Player(GameState *state) 
: Entity(state,true,entityName::entityPlayer), health(100),bulletSpeed(600),_colour(sf::Color(128,255,86,255)) 

이제이 모양이 모두 맞습니까? 생성자 본문에서 모든 작업을 수행하는 것보다 약간 낫습니다.

+0

이 경우 초기화하지 않고 단순히 생성자 본문에'bar'를 지정하지 않은 이유는 무엇입니까? – Pubby

+0

신체에서 수행하는 대신 초기화 도구 목록에 변수를 할당하는 것이 더 나은 프로그래밍 연습이라고 들었는데, 정확하지 않습니까? 또는 클래스의 직접 멤버 인 경우에만 init 목록을 사용해야합니까? – user1725794

+0

이니셜 라이저 목록에 * 변수를 지정하지 않으면 할당 연산자 대신 생성자를 사용한다는 것을 의미합니다. 이것은 주요 차이점입니다. 이처럼 간단한 코드 조각에서는 할당이 잘되어야하지만 실제 코드에서는 대답이 달라집니다. – Pubby

답변

5

클래스의 생성자에서 멤버 initialiser 목록 C 만 초기화 할 수 있습니다 CC

  • 가상 기본 클래스의 C
  • 직접 회원의

    • 직접 기본 클래스 (오지 않는다 너무 자주 올라간다)

    Th 기본 클래스의 멤버를 초기화하는 유일한 방법은 기본 클래스의 생성자를 사용하는 것입니다. 아니면 그냥 초기화를 무시한 다음 C의 생성자 본문에서 과제를 수행합니다. 후자는 회원 또는 참조에 대해 const에 사용할 수 없으며 일반적으로 초기화와 동일한 작업을 수행하지 않습니다.

  • +0

    const 구성원이나 참조 구성원이 문제가 될 수 있습니다. – David

    +0

    당신의 견해로는 어떤 방법이 가장 좋을까요? 나는 클래스 생성자에서 멤버를 초기화하는 것이 최선의 방법이 아니며 초기화리스트를 대신 사용해야한다고 들었다. 이 경우 두 번째 매개 변수를 사용하여 클래스 foo에 대해 또 다른 생성자를 만들어야합니까? – user1725794

    +0

    @ user1725794'Foo'가 당신의 통제하에 있다면, 적절한 생성자를주는 것이 올바른 일입니다. 클래스의 생성자는 모든 멤버를 적절한 방법으로 초기화해야합니다. 그리고'_bar'가 보호되어 있기 때문에 파생 된 클래스가 적합하다고 생각할 때 그것을 초기화하려고 할 수도 있습니다. 이를 위해'Foo'는 적절한 생성자가 필요합니다. – Angew

    1

    액세스하기 전에 기본 클래스를 초기화해야합니다. 기본 클래스의 멤버 변수를 초기화하려면 멤버를 초기화 할 기본 클래스 생성자를 호출해야합니다.

    2

    당신은 (는 const를하지 않은 경우) 몸에 초기화 목록에서 움직일 수 중 하나

    Bar() : Foo(10), _temp("something") 
    { 
        _bar = "something_else"; 
    } 
    

    또는 Foo하는 제 (아마도 보호) 생성자 제공 :

    class Foo 
    { 
    public: 
        Foo(int x) : _foo(x) 
        { 
    
        } 
    
    protected: 
        Foo(int x,std::string s) : _foo(x), _bar(s) 
        { 
        } 
    
    private: 
        int _foo; 
    
    protected: 
        std::string _bar; 
    }; 
    
    class Bar : public Foo 
    { 
    public: 
        Bar() : Foo(10,"something_else"), _temp("something") 
        { 
    
        } 
    
    private: 
        std::string _temp; 
    }; 
    
    1

    Foo의 생성자의 초기화 목록에 _bar을 넣을 수 있습니다. _bar에 항상 할당 할 필요가없는 경우 기본값을 사용할 수 있습니다.

    class Foo 
    { 
    public: 
        Foo(int x):_foo(x) 
        { 
        } 
    protected: 
        Foo(int x, string s) : _foo(x),_bar(s) 
        { 
    
        } 
    
    private: 
        int _foo; 
    
    protected: 
        std::string _bar; 
    }; 
    
    class Bar : public Foo 
    { 
    public: 
        Bar() : Foo(10,"something else"), _temp("something") 
        { 
    
        } 
    private: 
        std::string _temp; 
    }; 
    
    +0

    두 생성자 'Foo (10)'이 모호해진다. 첫 번째 생성자 또는 기본 인수를 삭제한다. –

    +0

    @DanielFrey 죄송 합니다만, 두 번째 생성자의 매개 변수에 기본값이있는 경우 애매하게됩니다. 그래서 부주의합니다. 업데이트 됨. 그 점을 지적 해 주셔서 감사합니다. – taocp

    관련 문제