C++クラスが継承されている場合、構造関数は虚関数でなければなりません.
1860 ワード
C++クラスが継承されている場合、構造関数は虚関数でなければなりません.虚関数でない場合、使用時に内在的な漏洩の問題がある可能性があります.
独自に設計したC++クラスアーキテクチャに継承関係がある場合は、親子クラスの構造関数キー設定に注意してください.虚関数は、ベースクラスでvirtualとして宣言され、派生クラスで再定義されたメンバー関数であり、メンバー関数の動的再ロードを実現します.クラスがベースクラスである場合、その構造関数は虚構造関数(ベースクラスの構造関数にvirtualキーワードを付ける)であるべきであり、サブクラスの構造関数を呼び出すことを保証することができます.
ベースクラスを超えた解析関数が虚解析関数ではない場合、ポインタがオブジェクトを指すタイプに基づいて解析関数を呼び出すのではなく、ポインタのタイプに基づいて解析関数を呼び出すので、サブクラスの解析関数は実行できません.テストコード:
資料:
https://blog.csdn.net/luoweifu/article/details/53780438
https://blog.csdn.net/tobefxz/article/details/14108891
独自に設計したC++クラスアーキテクチャに継承関係がある場合は、親子クラスの構造関数キー設定に注意してください.虚関数は、ベースクラスでvirtualとして宣言され、派生クラスで再定義されたメンバー関数であり、メンバー関数の動的再ロードを実現します.クラスがベースクラスである場合、その構造関数は虚構造関数(ベースクラスの構造関数にvirtualキーワードを付ける)であるべきであり、サブクラスの構造関数を呼び出すことを保証することができます.
ベースクラスを超えた解析関数が虚解析関数ではない場合、ポインタがオブジェクトを指すタイプに基づいて解析関数を呼び出すのではなく、ポインタのタイプに基づいて解析関数を呼び出すので、サブクラスの解析関数は実行できません.テストコード:
#include
#include
class BaseClass
{
public:
BaseClass()
: m_pValue(NULL)
{
}
/*virtual */~BaseClass()
{
delete m_pValue;
m_pValue = NULL;
std::cout << "BaseClass virtual construct." << std::endl;
}
void SetValue(int v)
{
if (!m_pValue)
{
m_pValue = new int(v);
}
else
{
*m_pValue = v;
}
}
private:
int* m_pValue;
};
class SubClass : public BaseClass
{
public:
SubClass()
: BaseClass()
, m_pstrName(NULL)
{
}
/*virtual */~SubClass()
{
delete m_pstrName;
m_pstrName = NULL;
std::cout << "SubClass virtual construct." << std::endl;
}
void SetName(const std::string& name)
{
if (!m_pstrName)
{
m_pstrName = new std::string(name);
}
else
{
*m_pstrName = std::string(name);
}
}
private:
std::string* m_pstrName;
};
int main()
{
BaseClass* pObj = new SubClass();
pObj->SetValue(10);
((SubClass*)pObj)->SetName("zhangsan");
delete pObj;
pObj = NULL;
return 0;
}
資料:
https://blog.csdn.net/luoweifu/article/details/53780438
https://blog.csdn.net/tobefxz/article/details/14108891