zoukankan      html  css  js  c++  java
  • 【C++缺省函数】 空类默认产生的6个类成员函数

    1、缺省构造函数。
    2、缺省拷贝构造函数。
    3、 缺省析构函数。
    4、缺省赋值运算符。

    5、缺省取址运算符。

    6、 缺省取址运算符 const。


    <span style="font-size:18px;">
    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 style="font-size:18px;">
    #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个成员函数:一个缺省的构造函数、一个拷贝构造函数、一个析构函数、一个赋值运算符、两个取址运算符。

    1. class Empty  
    2. {};  
    等价于:
    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. };  
    使用时的调用情况:
    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++编译器对这些函数的实现:

    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位不同的系统。

  • 相关阅读:
    SQL语句中case函数
    动态获取数据库表中的字段名
    Java实现最基本的集中排序
    服务器上产看报错的日志的方法
    数据结构顺序表Java实现
    JavaScript创建对象
    JavaScript的基础语法
    javascript介绍
    Java小项目迷你图书管理系统
    CDN——到底用还是不用?
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/6777304.html
Copyright © 2011-2022 走看看