2010-05-12 1 views
0

: 나는 객체 지향 프로그래밍에 새로운 아니에요C++ 클래스 파생 및 superconstructor와 혼란 이봐, 튜토리얼 C에서 + + 코드, 내가 혼란이 특정 부분을 발견

PlasmaTutorial1::PlasmaTutorial1(QObject *parent, const QVariantList &args) 
    : Plasma::Applet(parent, args), // <- Okay, Plasma = namespace, Applet = class 
    m_svg(this),     // <- A member function of class "Applet"? 
    m_icon("document")    // <- ditto? 
{ 
    m_svg.setImagePath("widgets/background"); 
    // this will get us the standard applet background, for free! 
    setBackgroundHints(DefaultBackground); 
    resize(200, 200); 
} 

을, 그래서 클래스 파생 슈퍼 클래스는 아무것도 복잡하지는 않지만이 구문은 나를 혼란스럽게 만들었습니다.

헤더 파일은 다음과 같이 클래스를 정의한다 : 위의

class PlasmaTutorial1 : public Plasma::Applet 
{ 

유사, 네임 스페이스 플라즈마 및 클래스 애플릿. 하지만 거기에 public은 무엇입니까?

나는 이미 개념을 알고 있지만 C++ 구문/방법을 이해하지 못한다고 우려한다.

this 질문에서 나는 이들을 "슈퍼 컨스트럭터 (superconstructors)"라고 불렀다. 적어도 그것이 내 기억 속에 갇힌 것이지만, 나는 이것을 완전히 확장하지 못했다.

첫 번째 발췌 문장을 다시 보면, 여기까지는 모두 Constructor::Class(...) : NS::SuperClass(...)입니다. 그러나 m_svg(this), m_icon("document")은 무엇을하고 있습니까? 이러한 특정 함수를 파생 클래스에 알리는 방법이 있습니까?

이 부분이 C++의 기본 사항입니까? 나는 C++에서 완전하게 잃어버린 것이 아니지만 C 언어로 가정에서 훨씬 더 많이 느낀다.

내가 지금까지해온 OOP의 대부분은 D, Ruby 또는 Python으로 수행되었다. 예를 들어 D에서 나는 단지 class MyClass : MySuperClass을 정의하고, 필자가 필요로하는 것을 재정의하고 수퍼 클래스의 생성자를 호출해야합니다.


좋아, 가정 정확한 답변의 일부, 이것은 ...

PlasmaTutorial1::PlasmaTutorial1(QObject *parent, const QVariantList &args) 
    : Plasma::Applet(parent, args), // <- Call the _parent_ constructor 
    m_svg(this),   // <- set m_svg (in the _derived_ class) to "this" 
    m_icon("document") // <- set m_icon (in the _derived_ class) to "document" 
{ 
    ... 
} 

을 ... 읽은 후?


테스트의 가정은 지금까지 확인되었습니다. 고마워요! 이기는 대답을 골라내는 것은 어려운 선택입니다 ...

+0

실제로 두 가지 질문이 있습니다. (1) 초기화 목록을 확인하십시오. (2) 보호 속성을 확인하십시오. – kennytm

+0

"공개"는 상속 유형을 의미합니다. 그것은 또한 보호되거나 사적 일 수 있습니다. – a1ex07

답변

3

당신이보고있는 것은 initialization list입니다. 그들은 C++ FAQ Lite에 의해 권장되고 회원이 생성자를 입력하기 전에 기본값을 취할 필요가 없기 때문에 회원 초기화 속도를 높입니다.

1

public은 부모의 public 클래스 멤버도 파생 클래스의 public 클래스 멤버가된다는 것을 의미합니다.

생성자의 초기화 목록에 표시되는 멤버는 파생 클래스 (m_svg, m_icon)의 멤버입니다. 부모 멤버는 초기화 할 수 없습니다.

2

멤버 함수가 아니며 초기화 목록입니다.

기본적으로, 일부 객체 지향 언어와는 달리, C++은 서브 클래스라는의 "범위 변경"의 개념을 가지고, 또한

PlasmaTutorial1::PlasmaTutorial1(QObject *parent, const QVariantList &args) 
    : Plasma::Applet(parent, args), // <- Call the parent constructor 
    m_svg(this),     // <- m_svg = this 
    m_icon("document")    // <- m_icon = "document" 
{ 
    m_svg.setImagePath("widgets/background"); 
    // this will get us the standard applet background, for free! 
    setBackgroundHints(DefaultBackground); 
    resize(200, 200); 
} 

의미한다.기본적으로 상속 구문의 public 키워드는 기본 클래스에서 상속 된 공개적으로 액세스 할 수있는 멤버가 파생 클래스에서 공개적으로 액세스 할 수 있음을 의미합니다.

private 키워드로 상속 된 클래스는 마찬가지로 하위 클래스의 수퍼 클래스 개인에게 공개적으로 액세스 할 수있는 모든 구성원을 비공개로 만듭니다.

2
PlasmaTutorial1::PlasmaTutorial1(QObject *parent, const QVariantList &args) 
    : Plasma::Applet(parent, args), // <- Okay, Plasma = namespace, Applet = class 
    m_svg(this),     // <- A member function of class "Applet"? 
    m_icon("document")    // <- ditto? 

이것은 초기화 목록입니다. 이 클래스를 사용하여 멤버 및/또는 기본 클래스를 초기화 할 수 있습니다. 작은 (그러나 완벽한) 예제를 생각해 봅시다 :이 경우

class base { 
    int v; 
public: 
    base(int init) : v(val) {} 
}; 

을의 v(val) 부분은 초기화 목록입니다.

base(int init) { v = init; } 

의 차이는 당신이 const의 구성원이있는 경우 (하나의 예를 들어) 발생 : 우리가 int를 초기화하고 있기 때문에, 거의 동등한가 있습니다. const 변수는 초기화해야하지만 에 할당 할 수 없습니다. 당신은 클래스의 구성원으로 참조가있는 경우

class X { 
    int const a; 
public: 
    X(int init) : a(init) {} 
}; 

같은 상황이 발생 : 따라서, (비 정적) const 부재력 당신은 초기화 목록을 사용합니다.

클래스 PlasmaTutorial1 : 공공 플라즈마 :: 위

유사 애플릿, 네임 스페이스 플라즈마 및 클래스 애플릿. 그러나 대중은 그곳에서 무엇을하고 있습니까?

대중은 단순히 공용 상속을 지정하기 때문에 기본 클래스의 public은 파생 클래스에서 public으로 유지됩니다. private 상속을 지정할 수도 있습니다.이 경우 부모로부터 상속 된 모든 것이 파생 클래스에서 private이됩니다. 또한 개인 상속을 사용하면 파생에서 기본으로의 암시 적 변환이 없습니다.

일반적으로 디자인 관점에서 상속이라고 생각하는 모든 것은 C++ 구현에서 공용 상속으로 모델링됩니다. 개인 상속은 보통 구현에만 사용됩니다 (일반적으로 첨부 된 의미는 "A"가 아니라 "측면에서 구현 됨"입니다).