关于c++的覆盖与复写,写了个测试程序,以明确一些概念。发此博客以记录。
1.c++中的多态只是发生在指针或者引用上,对象赋值不存在多态。(见例子中的funcRecoverAssignTest())
2.对象赋值亦会赋值基类变量。(同样见funcRecoverAssignTest())
3.当不声明成员函数为多态时(virtual关键字),子类签名相同的成员函数形成覆盖。此时基类指针不会去查虚表,调用的是基类的成员函数(见funcRecoverTest())
4.引用表现于指针基本一样。
综上推断c++类与对象模型:
1.c++类模型在编译时确定,运行时在堆上分配的是存放成员变量的空间。
2.当声明成员函数为多态时,对象会生成一个虚表,保存多态的成员函数列表。当指针调用时,会查找对象自带的虚表,找到正确的多态函数。
3.如果成员函数不声明为多态,则分配对象时,不会将其列入多态成员函数的虚表,侧当调用函数时,调用的为原对象的成员函数,从而不会形成多态。
代码:
#include <iostream>
using namespace std;
class Base
{
public:
Base(int i = 1):m_iTag(i)
{
}
virtual void VPrint()
{
cout<<"from base calss virtual print:"<<endl;
print();
}
void NPrint()
{
cout<<"from base calss Nonmal print:"<<endl;
print();
}
virtual void PrintTag()
{
cout<<"the tag is "<<m_iTag<<endl;
}
int GetTag()
{
return m_iTag;
}
protected:
virtual void print()
{
cout<<"This is the base class"<<endl;
cout<<endl;
}
void SetTag(int i)
{
m_iTag = i;
}
private:
int m_iTag;
};
class Super : public Base
{
public:
Super():Base(2),m_iSuperTag(3)
{
}
void VPrint()
{
cout<<"from Super calss virtual print:"<<endl;
print();
}
void NPrint()
{
cout<<"from Super calss Nonmal print:"<<endl;
print();
}
void PrintTag()
{
cout<<"from super print tag:"<<endl;
Base::PrintTag();
cout<<"the super tag is "<<m_iSuperTag<<endl;
}
protected:
void print()
{
cout<<"This is the Super class"<<endl;
cout<<endl;
}
private:
int m_iSuperTag;
};
void funcRecoverTest()
{
cout<<"This is recover point test:"<<endl<<endl;
Super aSuper;
Base * paBase = &aSuper;
paBase->VPrint();
paBase->NPrint();
paBase->PrintTag();
cout<<endl;
}
void funcRecoverAssignTest()
{
cout<<"This is recover assign test:"<<endl<<endl;
Super aSuper;
Base aBase = aSuper;
aBase.VPrint();
aBase.NPrint();
aBase.PrintTag();
cout<<endl;
}
void funcRefTest()
{
cout<<"This is ref test:"<<endl<<endl;
Super aSuper;
Base &aBase = aSuper;
aBase.VPrint();
aBase.NPrint();
aBase.PrintTag();
cout<<endl;
}
void printNextTest()
{
cout<<endl<<endl;
}
void funcGrammerInheritancyTest()
{
funcRecoverTest();
printNextTest();
funcRecoverAssignTest();
printNextTest();
funcRefTest();
printNextTest();
}
运行结果:
This is recover point test:
from Super calss virtual print:
This is the Super class
from base calss Nonmal print:
This is the Super class
from super print tag:
the tag is 2
the super tag is 3
This is recover assign test:
from base calss virtual print:
This is the base class
from base calss Nonmal print:
This is the base class
the tag is 2
This is ref test:
from Super calss virtual print:
This is the Super class
from base calss Nonmal print:
This is the Super class
from super print tag:
the tag is 2
the super tag is 3
请按任意键继续. . .