using namespace std;
class Base
{
public:
Base(){base = 1; cout<<"Base!\n";}
virtual ~Base(){cout<<"~Base!\n";}
virtual void say(){cout<<"hello Base\n";}
private:
int base;
static int count;
};
class Derive : public Base
{
public:
Derive(){derive = 2;}
virtual ~Derive(){cout<<"~Derive!\n";}
virtual void say(){cout<<"hello Derive\n";}
private:
int derive;
};
int main(int argc, char* argv[])
{
Base *pd=new Derive;
pd->say();
cout<<sizeof(pd)<<endl;
cout<<sizeof(Base)<<endl;
cout<<sizeof(Derive)<<endl;
delete pd;
return 0;
}
我们可以观察C++对象模型:
在此模型中,非静态数据成员被配置于每一个类对象之内,静态数据成员则被存放在所有的类对象之外,静态和非静态的函数成员也被放在所有的类对象之外,虚函数则以下面两个步骤支持:
(1) 每一个类产生一堆指向虚函数的指针,放在表格中,这个表格被称为虚表格(vtbl)。
(2) 每一个类对象被添加一个指针,指向相关的虚表,这个指针被称为vptr,vptr的设定和重置都由每一个class的构造、虚构和赋值拷贝运算符自动完成,每一个类所关联的type_info object也经由虚表格被指出来,通常放在表格的第一个表格处。
内存分布继承内前面的包含父类的成员!
输出的结果是:Base! Hello Derive 4 8 12 ~Derive! ~Base
3,千万不要返回局部对象的引用。当函数执行完毕时,将释放分配给局部对象的存储空间。此时,对局部对象的引用就会指向不确定的内存。如:
const string &manip(const string &s)
{
string ret =s;
return ret; //wrong:returning reference to a local object
}
2)返回非引用类型:函数的返回值用于初始化在跳用函数出创建的临时对象。用函数返回值初始化临时对象与用实参初始化形参的方法是一样 的。如果返回类型不是引用,在调用函数的地方会将函数返回值复制给临时对象。且其返回值既可以是局部对象,也可以是求解表达式的结果。返回局部对象可以是一个局部对象,会默认调用复制构造函数进行复制!