C ++を使用して派生クラスから親関数を呼び出すにはどうすればよいですか?たとえば、というクラスとparent
、child
親から派生したというクラスがあります。各クラス内にはprint
関数があります。子の印刷関数の定義で、親の印刷関数を呼び出したいと思います。これを行うにはどうすればよいですか?
C ++を使用して派生クラスから親関数を呼び出すにはどうすればよいですか?たとえば、というクラスとparent
、child
親から派生したというクラスがあります。各クラス内にはprint
関数があります。子の印刷関数の定義で、親の印刷関数を呼び出したいと思います。これを行うにはどうすればよいですか?
回答:
基本的なクラスで定義されている場合は、派生クラスで自動的に使用できるように関数を呼び出します(そうでない場合private
)。
派生クラスに同じシグネチャを持つ関数がある場合は、基本クラスの名前の後に2つのコロンを追加することで、関数を明確にすることができますbase_class::foo(...)
。JavaやC#とは異なり、C ++には「基本クラス」(または)のキーワードがないことに注意してください。C++は多重継承をサポートしているため、あいまいになる可能性があります。super
base
class left {
public:
void foo();
};
class right {
public:
void foo();
};
class bottom : public left, public right {
public:
void foo()
{
//base::foo();// ambiguous
left::foo();
right::foo();
// and when foo() is not called for 'this':
bottom b;
b.left::foo(); // calls b.foo() from 'left'
b.right::foo(); // call b.foo() from 'right'
}
};
ちなみに、基本クラスの1つを他のクラスで参照する方法がないため、同じクラスから直接2回派生することはできません。
class bottom : public left, public left { // Illegal
};
template<class A, class B> class C: public A, public B {};
は、コードの使用方法に応じて(AとBが同じになる)理由により、2つのタイプが同じになる場合があり、2つまたは3つになる場合があります。あなたがしたことに気づいていない誰かからの抽象化層の方法。
using namespace std
。
という名前の親クラスとという名前のParent
子クラスがChild
ある場合、次のようなことができます。
class Parent {
public:
virtual void print(int x);
}
class Child : public Parent {
void print(int x) override;
}
void Parent::print(int x) {
// some default behavior
}
void Child::print(int x) {
// use Parent's print method; implicitly passes 'this' to Parent::print
Parent::print(x);
}
Parent
はクラスの実際の名前であり、キーワードではないことに注意してください。
foo()
と類似し、ここでprint()
または別の機能?そして、private
継承を使用してベースから継承された詳細を非表示にし、公開したいpublic
ものにシャドウ機能を提供するということですか?
foo()
に似ていましたprint()
。print()
このコンテキストではより理にかなっていると思うので、使用に戻りましょう。誰かが特定のデータ型に対して一連の操作を実行するクラスを作成し、いくつかのアクセサを公開し、print(obj&)
メソッドを持っているとしましょう。動作する新しいクラスが必要array-of-obj
ですが、他のすべては同じです。構成により、多くのコードが重複します。継承により、print(array-of-obj&)
ループ呼び出しprint(obj&)
でそれが最小限に抑えられますが、クライアントには呼び出しprint(obj&)
が意味をなさないため、呼び出しを望まないのです
基本クラスが呼び出されBase
、関数が呼び出されたFooBar()
場合は、次を使用して直接呼び出すことができますBase::FooBar()
void Base::FooBar()
{
printf("in Base\n");
}
void ChildOfBase::FooBar()
{
Base::FooBar();
}
MSVCにはそのためのMicrosoft固有のキーワードがあります:__super
MSDN:オーバーライドする関数の基本クラスの実装を呼び出すことを明示的に示すことができます。
// deriv_super.cpp
// compile with: /c
struct B1 {
void mf(int) {}
};
struct B2 {
void mf(short) {}
void mf(char) {}
};
struct D : B1, B2 {
void mf(short) {
__super::mf(1); // Calls B1::mf(int)
__super::mf('s'); // Calls B2::mf(char)
}
};
typdef
は親のようなものを好むでしょうsuper
。
__super
。ここでは、代替案として言及しました。開発者はコンパイラを理解し、その機能の長所と短所を理解する必要があります。
基本クラスのメンバー関数のアクセス修飾子が保護されているか、パブリックである場合、派生クラスから基本クラスのメンバー関数を呼び出すことができます。派生メンバー関数から基本クラスの非仮想メンバー関数と仮想メンバー関数を呼び出すことができます。プログラムを参照してください。
#include<iostream>
using namespace std;
class Parent
{
protected:
virtual void fun(int i)
{
cout<<"Parent::fun functionality write here"<<endl;
}
void fun1(int i)
{
cout<<"Parent::fun1 functionality write here"<<endl;
}
void fun2()
{
cout<<"Parent::fun3 functionality write here"<<endl;
}
};
class Child:public Parent
{
public:
virtual void fun(int i)
{
cout<<"Child::fun partial functionality write here"<<endl;
Parent::fun(++i);
Parent::fun2();
}
void fun1(int i)
{
cout<<"Child::fun1 partial functionality write here"<<endl;
Parent::fun1(++i);
}
};
int main()
{
Child d1;
d1.fun(1);
d1.fun1(2);
return 0;
}
出力:
$ g++ base_function_call_from_derived.cpp
$ ./a.out
Child::fun partial functionality write here
Parent::fun functionality write here
Parent::fun3 functionality write here
Child::fun1 partial functionality write here
Parent::fun1 functionality write here
virtual
!
親スコープ解決演算子を使用して親メソッドを呼び出します。
Parent :: method()
class Primate {
public:
void whatAmI(){
cout << "I am of Primate order";
}
};
class Human : public Primate{
public:
void whatAmI(){
cout << "I am of Human species";
}
void whatIsMyOrder(){
Primate::whatAmI(); // <-- SCOPE RESOLUTION OPERATOR
}
};
struct a{
int x;
struct son{
a* _parent;
void test(){
_parent->x=1; //success
}
}_son;
}_a;
int main(){
_a._son._parent=&_a;
_a._son.test();
}
参考例。