サブクラスでベースクラスの純虚関数のアクセス表現ドメインを変更する
4375 ワード
サブクラスでベースクラスの純虚関数のアクセス表現ドメインを変更する
虚関数についての学習ノート.間違いや改善すべき点を指摘してください.
内容:
ベースクラスの虚関数はprivateとして宣言され、サブクラスではpublicとして宣言されます.
ベースクラスの虚関数はpublicとして宣言され、サブクラスではprivateとして宣言されます.
虚関数では非虚関数が呼び出され、非虚関数では虚関数が呼び出されます.
多くの人が簡単に見えるかもしれませんが、虚関数テーブルを理解するのに役立つと思います.
テストコード:
コメントされた2行は、コンパイル時にエラーが表示されます.
testVirtual.cpp: In function ‘int main()’:
testVirtual.cpp:9: error: ‘virtual void Base::print()’ is private
testVirtual.cpp:25: error: within this context
testVirtual.cpp:18: error: ‘virtual void DeriveFirst::info()’ is private
testVirtual.cpp:28: error: within this context
静的タイプは、アクセス可能な関数とアクセス不可能な関数を決定するので、b->print()、df->info()はアクセス不可をプロンプトします.
動的タイプは、特定の関数が呼び出されるかどうかを決定するので、b->info()はそのサブクラスのinfo関数を呼び出します.興味深いことに、サブクラスのinfo()はprivateです.この場合、虚関数テーブルが機能するためです.
虚関数が他の関数を呼び出すと、その関数が虚関数であるかどうかにかかわらず、呼び出されるのはサブクラスで実現される虚関数です.
個別出力:
int A::fun_a
int B::fun_a
int B::fun_b
test呼び出しfun_b時に虚関数で探し、サブクラスのfun_を呼び出すb,サブクラスのfun_b実装、使用する自然は再定義後のfun_a.アセンブリに詳しい人は、アセンブリがここにあるジャンプ命令を見ることができます.アセンブリコードにfun_bの実装でここで呼び出されたのはB::fun_a.
int B::fun_a
int B::fun_a
int A::fun_b
test呼び出しfun_b時に虚関数表で探すことはなく、直接A::fun_を呼び出すb、ただしfun_に呼び出されるaサブクラスfun_を呼び出す必要があるかどうかをチェックします.a.
虚関数についての学習ノート.間違いや改善すべき点を指摘してください.
内容:
ベースクラスの虚関数はprivateとして宣言され、サブクラスではpublicとして宣言されます.
ベースクラスの虚関数はpublicとして宣言され、サブクラスではprivateとして宣言されます.
虚関数では非虚関数が呼び出され、非虚関数では虚関数が呼び出されます.
多くの人が簡単に見えるかもしれませんが、虚関数テーブルを理解するのに役立つと思います.
テストコード:
#include <iostream>
using namespace std;
class Base {
public:
virtual void info() = 0;
private:
virtual void print() = 0;
};
class DeriveFirst : public Base {
public:
virtual void print() { cout << "DeriveFirst::Base" << endl; }
private:
virtual void info() { cout << "DeriveFirst::info" << endl; }
};
int main()
{
Base *b = new DeriveFirst;
DeriveFirst *df = new DeriveFirst;
//b->print();
df->print();
b->info();
//df->info();
return 0;
}
コメントされた2行は、コンパイル時にエラーが表示されます.
testVirtual.cpp: In function ‘int main()’:
testVirtual.cpp:9: error: ‘virtual void Base::print()’ is private
testVirtual.cpp:25: error: within this context
testVirtual.cpp:18: error: ‘virtual void DeriveFirst::info()’ is private
testVirtual.cpp:28: error: within this context
静的タイプは、アクセス可能な関数とアクセス不可能な関数を決定するので、b->print()、df->info()はアクセス不可をプロンプトします.
動的タイプは、特定の関数が呼び出されるかどうかを決定するので、b->info()はそのサブクラスのinfo関数を呼び出します.興味深いことに、サブクラスのinfo()はprivateです.この場合、虚関数テーブルが機能するためです.
虚関数が他の関数を呼び出すと、その関数が虚関数であるかどうかにかかわらず、呼び出されるのはサブクラスで実現される虚関数です.
//test1.cpp
#include <iostream>
using namespace std;
class A {
public:
void fun_a() { cout << "int A::fun_a" << endl; }
virtual void fun_b() {
fun_a();
cout << "int A::fun_b" << endl;
}
};
class B : public A {
private:
void fun_a() { cout << "int B::fun_a" << endl; }
void fun_b() {
fun_a();
cout << "int B::fun_b" << endl;
}
};
int main()
{
A *test = new B();
test->fun_a();
test->fun_b();
return 0;
}
//test2.cpp
#include <iostream>
using namespace std;
class A {
public:
virtual void fun_a() { cout << "int A::fun_a" << endl; }
void fun_b() {
fun_a();
cout << "int A::fun_b" << endl;
}
};
class B : public A {
private:
void fun_a() { cout << "int B::fun_a" << endl; }
void fun_b() {
fun_a();
cout << "int B::fun_b" << endl;
}
};
int main()
{
A *test = new B();
test->fun_a();
test->fun_b();
return 0;
}
個別出力:
int A::fun_a
int B::fun_a
int B::fun_b
test呼び出しfun_b時に虚関数で探し、サブクラスのfun_を呼び出すb,サブクラスのfun_b実装、使用する自然は再定義後のfun_a.アセンブリに詳しい人は、アセンブリがここにあるジャンプ命令を見ることができます.アセンブリコードにfun_bの実装でここで呼び出されたのはB::fun_a.
int B::fun_a
int B::fun_a
int A::fun_b
test呼び出しfun_b時に虚関数表で探すことはなく、直接A::fun_を呼び出すb、ただしfun_に呼び出されるaサブクラスfun_を呼び出す必要があるかどうかをチェックします.a.