파생 클래스 생성자에서 기본 클래스 멤버 변수를 어떻게 초기화 할 수 있습니까?
왜 이렇게 할 수 없습니까?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
의 멤버가 아니기 때문에 a
및 b
in을 초기화 할 수 없습니다 . 의 멤버 이므로 초기화 만 가능합니다. 공개로 설정 한 다음에서 할당 할 수 있지만 캡슐화를 파괴 할 수 있으므로 권장되는 옵션이 아닙니다. 대신에 생성자 만들 수 있도록 (또는 서브 클래스 )을 초기화를 :B
B
A
A
B
A
B
A
class A
{
protected:
A(int a, int b) : a(a), b(b) {} // Accessible to derived classes
// Change "protected" to "public" to allow others to instantiate A.
private:
int a, b; // Keep these variables private in A
};
class B : public A
{
public:
B() : A(0, 0) // Calls A's constructor, initializing a and b in A to 0.
{
}
};
옆으로가 있다는 사실 떠나 private
있기 때문에, a
그리고 b
의 구성원 A
들이 초기화되는 것을 의미한다, A
의 생성자를, 다른 클래스의 생성자에 의해 (파생 여부) 없습니다.
시험:
class A
{
int a, b;
protected: // or public:
A(int a, int b): a(a), b(b) {}
};
class B : public A
{
B() : A(0, 0) {}
};
어쨌든 아무도 가장 간단한 방법을 나열하지 않았습니다.
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
You can't access base members in the initializer list, but the conmstructor itself, just as any other member method, may access public
and protected
members of the base class.
# include<stdio.h>
# include<iostream>
# include<conio.h>
using namespace std;
class Base{
public:
Base(int i, float f, double d): i(i), f(f), d(d)
{
}
virtual void Show()=0;
protected:
int i;
float f;
double d;
};
class Derived: public Base{
public:
Derived(int i, float f, double d): Base( i, f, d)
{
}
void Show()
{
cout<< "int i = "<<i<<endl<<"float f = "<<f<<endl <<"double d = "<<d<<endl;
}
};
int main(){
Base * b = new Derived(10, 1.2, 3.89);
b->Show();
return 0;
}
It's a working example in case you want to initialize the Base class data members present in the Derived class object, whereas you want to push these values interfacing via Derived class constructor call.
While this is usefull in rare cases (if that was not the case, the language would've allowed it directly), take a look at the Base from Member idiom. It's not a code free solution, you'd have to add an extra layer of inheritance, but it gets the job done. To avoid boilerplate code you could use boost's implementation
Why can't you do it? Because the language doesn't allow you to initializa a base class' members in the derived class' initializer list.
How can you get this done? Like this:
class A
{
public:
A(int a, int b) : a_(a), b_(b) {};
int a_, b_;
};
class B : public A
{
public:
B() : A(0,0)
{
}
};
If you don't specify visibility for a class member, it defaults to "private". You should make your members private or protected if you want to access them in a subclass.
Aggregate classes, like A in your example(*), must have their members public, and have no user-defined constructors. They are intialized with initializer list, e.g. A a {0,0};
or in your case B() : A({0,0}){}
. The members of base aggregate class cannot be individually initialized in the constructor of the derived class.
(*) To be precise, as it was correctly mentioned, original class A
is not an aggregate due to private non-static members
'program story' 카테고리의 다른 글
emacs에서 활성 부 모드를 어떻게 나열합니까? (0) | 2020.08.15 |
---|---|
Python List Comprehension을 사용하여 조건에 따라 요소의 인덱스 찾기 (0) | 2020.08.15 |
Application.ThreadException과 AppDomain.CurrentDomain.UnhandledException의 차이점은 무엇입니까? (0) | 2020.08.15 |
Maven의 DistributionManagement 조직 전체를 지정하는 방법은 무엇입니까? (0) | 2020.08.15 |
WebDriverException : 알 수없는 오류 : Chrome 브라우저를 시작하는 동안 DevToolsActivePort 파일이 존재하지 않습니다. (0) | 2020.08.15 |