【C++缺省函数】空类默认产⽣的6个类成员函数
1、缺省构造函数。
2、缺省拷贝构造函数。
3、缺省析构函数。
4、缺省赋值运算符。
5、缺省取址运算符。
6、缺省取址运算符 const。
<span >
class A
{
public:
A(){}//缺省构造函数
A(const A&){}//拷贝构造函数
~A(){}//析构函数
A&operator=(const A&){}//赋值运算符
A*operator&(){}//取址运算符
const A*operator&()const{}//取址运算符 const
};
</span>
在C++中。编译器会为空类提供哪些默认成员函数?分别有什么样的功能呢?
空类,声明时编译器不会⽣成不论什么成员函数
对于空类。编译器不会⽣成不论什么的成员函数。仅仅会⽣成1个字节的占位符。
有时可能会以为编译器会为空类⽣成默认构造函数等,其实是不会的。编译器仅仅会在须要的时候⽣成6个成员函数:⼀个缺省的构造函数、⼀个拷贝构造函数、⼀个析构函数、⼀个赋值运算符、⼀对取址运算符和⼀个this指针。
指向类成员函数的指针
代码:
<span >
#include <iostream>
using namespace std;
class Empty_one
{
};
class Empty_two
{};
class Empty_three
{
virtual void fun() = 0;
};
class Empty_four :  public Empty_two, public Empty_three
{
};
int main()
{
cout<<"sizeof(Empty_one):"<<sizeof(Empty_one)<<endl;
cout<<"sizeof(Empty_two):"<<sizeof(Empty_two)<<endl;
cout<<"sizeof(Empty_three):"<<sizeof(Empty_three)<<endl;
cout<<"sizeof(Empty_four):"<<sizeof(Empty_four)<<endl;
return 0;
}
</span>
结果:
分析:
类Empty_one、Empty_two是空类,但空类相同能够被实例化。⽽每⼀个实例在内存中都有⼀个独⼀⽆⼆的地址,为了达到这个⽬的。编译器往往会给⼀个空类隐含的加⼀个字节。这样空类在实例化后在内存得到了独⼀⽆⼆的地址,所以
sizeof(Empty_one)和sizeof(Empty_two)的⼤⼩为1。
类Empty_three⾥⾯因有⼀个纯虚函数,故有⼀个指向虚函数的指针(vptr),32位系统分配给指针的⼤
⼩为4个字节,所以sizeof(Empty_three)的⼤⼩为4。
类Empty_four继承于Empty_two和Empty_three,编译器取消Empty_two的占位符。保留⼀虚函数表。故⼤⼩为4。
2、空类。定义时会⽣成6个成员函数
当空类Empty_one定义⼀个对象时Empty_one pt;sizeof(pt)仍是为1,但编译器会⽣成6个成员函数:⼀个缺省的构造函数、⼀个拷贝构造函数、⼀个析构函数、⼀个赋值运算符、两个取址运算符。
[html]
1. class Empty
2. {};
等价于:
[html]
1. class Empty
2. {
3.  public:
4.    Empty();                            //缺省构造函数
5.    Empty(const Empty &rhs);            //拷贝构造函数
6.    ~Empty();                          //析构函数
7.    Empty& operator=(const Empty &rhs); //赋值运算符
8.    Empty* operator&();                //取址运算符
9.    const Empty* operator&() const;    //取址运算符(const版本号)
10. };
使⽤时的调⽤情况:
[html]
1. Empty *e = new Empty();    //缺省构造函数
2. delete e;                  //析构函数
3. Empty e1;                  //缺省构造函数
4. Empty e2(e1);              //拷贝构造函数
5. e2 = e1;                  //赋值运算符
6. Empty *pe1 = &e1;          //取址运算符(⾮const)
7. const Empty *pe2 = &e2;    //取址运算符(const)
C++编译器对这些函数的实现:
[html]
1. inline Empty::Empty()                          //缺省构造函数
2. {
3. }
4. inline Empty::~Empty()                        //析构函数
5. {
6. }
7. inline Empty *Empty::operator&()              //取址运算符(⾮const)
8. {
9.  return this;
10. }
11. inline const Empty *Empty::operator&() const    //取址运算符(const)
12. {
13.  return this;
14. }
15. inline Empty::Empty(const Empty &rhs)          //拷贝构造函数
16. {
17.  //对类的⾮静态数据成员进⾏以"成员为单位"逐⼀拷贝构造
18.  //固定类型的对象拷贝构造是从源对象到⽬标对象的"逐位"拷贝
19. }
20.
21. inline Empty& Empty::operator=(const Empty &rhs) //赋值运算符
22. {
23.  //对类的⾮静态数据成员进⾏以"成员为单位"逐⼀赋值
24.  //固定类型的对象赋值是从源对象到⽬标对象的"逐位"赋值。
25. }
⽐如:m是类C中的⼀个类型为T的⾮静态成员变量。若C没有声明拷贝构造函数(赋值运算符)。 m将会通过T的拷贝构造函数(赋值运算符)被拷贝构造(赋值);该规则递归应⽤到m的数据成员,直到到⼀个拷贝构造函数(赋值运算符)或固定类型(⽐如:int、double、指针等)为⽌。
三、总结
上述执⾏结果依赖于编译器和64位、32位不同的系统。