1.对象模型
C++对象模型中,non static数据成员被放置到对象内部,static数据成员,static and non static函数成员均被放到对象之外。
而对于虚函数的支持则分两步完成:
1.每一个class产生一堆指向虚函数的指针,放在表格之中。这个表格称之为虚函数表(virtual table,vtbl)。
2.每一个对象被添加了一个指针,指向相关的虚函数表vtbl。通常这个指针被称为vptr。vptr的设定(setting)和重置(resetting)都由每一个class的构造函数,析构函数和拷贝赋值运算符自动完成。
例如图1中,由于A类中有虚函数,所以A类的对象中有自己的两个成员变量m_data1、m_date2和一个指向vtbl的指针(vptr)。B类是A类的子类,B类对象除了有父类对象所有成员和vptr外,还有自己的成员m_data3。这些对象占用内存的大小由它们的成员变量和vptr指针决定,在不同的编译环境下它们的内存大小会有所不同。
2.const
当类中成员函数的const和non-const版本同时存在时,const对象只会调用const版本,non-const对象只会调用non-const版本。
const对象和non-const对象都可以调用const成员函数;
non-const对象可以调用non-const成员函数而const对象则不可以。
例如以下程序:
#include <iostream>
class Foo
{
public:
Foo(int id) : id_(id) { }
void print() const {
std::cout<<"const print id:"<<id_<<std::endl;
}
void print() {
std::cout<<"non-const print id:"<<id_<<std::endl;
}
void say() {
std::cout<<"say id:"<<id_<<std::endl;
}
void tell() const {
std::cout<<"tell id:"<<id_<<std::endl;
}
private:
int id_;
};
int main()
{
Foo a1 = Foo(6);
const Foo a2 = Foo(5);
a1.print();
a2.print();
a1.say();
a1.tell();
//a2.say(); //[Error] passing 'const Foo' as 'this' argument of 'void Foo::say()' discards qualifiers [-fpermissive]
return 0;
}
图 2 测试结果
例中print函数同时有const和non-const版本,const对象和non-const对象都能调用对应的版本。而const对象调用non-const成员函数时编译会出错。
3.重载new和delete
C++中new,delete,new[],delete[]是可以重载的,这样可以在程序执行new或delete时另外地实现我们自己所想要的操作。
new,delete,new[],delete[]的重载分为全局重载和对特定类的重载。
例如:
全局重载
//global operator new/delete
void* myAlloc(size_t size){
return malloc(size);
}
void myFree(void* ptr){
return free(ptr);
}
inline void* operator new(size_t size){
std::cout<<"global new() \n";
return myAlloc(size);
}
inline void operator delete(void* ptr){
std::cout<<"global delete() \n";
return myFree(ptr);
}
对A类对象new,delete的重载
class A {
int id;
public:
A(int i):id(i){
std::cout<<"A构造 \n";
}
~A(){
std::cout<<"A析构 \n";
}
static void* operator new(size_t size);
static void operator delete(void* pdead,size_t size);
};
//member operator new/delete
void* A::operator new(size_t size) {
A* p = (A*)malloc(size);
std::cout<<...........;
return p;
}
void A::operator delete(void* pdead,size_t size) {
std::cout<<...........;
free(pdead);
}
网友评论