zoukankan      html  css  js  c++  java
  • 深入探索C++对象模型-语义

      有三种情况,这将是一个object的内容,以及一class object早期值:
               
    Cpp代码  收藏代码
    1. class X { ... };  
    2. X x;  
    3.   
    4. X xx = x;               // 情况1,赋值对象  
    5.   
    6. extern void foo( X x);  
    7.   
    8. void bar()  
    9. {  
    10.      
    11.     X xx;  
    12.   
    13.     foo( xx );         // 情况2,作为參数  
    14.   
    15. }  
    16.   
    17. X foo_bar()  
    18. {  
    19.   
    20.     X xx;  
    21.   
    22.     return xx;         // 情况3。作为返回值  
    23. }  

        
                   
            Default Memberwise Initalization

                假设class 没有提供一个explicit copy constructor又当怎样?当class object 以 “同样class的还有一个object”作为初值时,其内是以所谓的default memberwise initalization手法完毕的。也就是把每个内建的或派生的data member的值,从某个object拷贝一份到还有一个object身上。

    只是它不会拷贝当中的member class object, 而是以递归的方式实行memberwise initalization.
               
                样例:

    Cpp代码  收藏代码
    1. class String  
    2. {  
    3.   
    4.     public:  
    5.      
    6.         //..没有explicit copy constructor  
    7.   
    8.     private:  
    9.   
    10.         char *str;  
    11.         int   len;  
    12.      
    13. };             
    14.   
    15. class Word  
    16. {  
    17.     public:  
    18.      
    19.         //..没有explicit copy constructor  
    20.     private:  
    21.   
    22.         int _occurs;  
    23.         String _word;  //String object成为class word的一个member. 此处以递归的方式实行memberwise initalization.  
    24.                   // Word 是否合成 copy constructor 取决于 bitwise copy semantics.  
    25.                 //此样例不合成copy constructor 编译器会自己主动复制每个数据成员  
    26. };  

     
                    指出一个错误概念:“假设一个class没有定义copy constructor。编译器就自己主动为它产生出一个”这句话不正确
                    正确的概念:Default constructor 和 copy constructor在必要的时候才由编译器产生出来。“必要”意指当class不展现bitwise copy semantics时。

            Bitwise Copy Semantics(位逐次拷贝)

                上例展示了Bitwise copy Semantics.

                有一点非常值得注意:在被合成出来的copy constructor中,如整数、指针、数组等等的nonclass memebers也都会被复制。正如我们所期待的一样。   

            不要Bitwise Copy Semantics
           
                有四种情况不展示Bitwise Copy Semantics, 不展示的时候须要编译器合成copy constructor:

                    (1)当class内含一个member object而后者的class声明有一个copy constructor时
                    (2)当class继承自一个base class 而后者存在有一个copy constructor时
                    (3)当class声明了一个或多个virtual functions时
                    (4)当class派生自一个继承串链,当中有一个或多个virtual base classes时

            结论:假设是自己定义复制构造函数时,须要自己把每个数据成员复制;假设是没有自己定义复制构造函数。不管是合成或非合成,编译器都会自己主动复制每个数据成员。复制构造函数的用途是:假设构造函数中存在动态内存分配,则必须定义复制构造函数,否则会出现“指针悬挂问题”。

    Cpp代码  收藏代码
    1. class A  
    2. {  
    3.     private:  
    4.         int *p;  
    5.   
    6.     public:  
    7.         A()  
    8.         {  
    9.             p = new int(3);  
    10.         }  
    11. };      

     
           
            在这样的情况下,复制对象。会造成两个对象的成员指向同一地址。

            又一次设定Virtual Table的指针
       
                样例:

    Cpp代码  收藏代码
    1. class ZooAninal  
    2. {  
    3.     public:  
    4.         ZooAnimal();  
    5.         virtual ~ZooAnimal();  
    6.   
    7.         virtual void animate();  
    8.         virtual void draw();         
    9. };  
    10.   
    11. class Bear : public ZooAnimal()  
    12. {  
    13.      
    14.     public:  
    15.         Bear();  
    16.         void animate();  
    17.         void draw();     
    18.         virtual void dance();  
    19.   
    20. };  
     
                    Bear yogi;
                    Bear winnie = yogi;

                    把yogi 的vptr值拷贝给winnie的vptr是安全的

                   

     

                    ZooAnimal franny = yogi; // 这会发生分割行为

                   

     

                    合成出来的ZooAinmal copy constructor会明白设定object的vptr指向ZooAnimal class的virtual table,而不是直接从右手边的class object中将其vptr现值拷贝过来。


           

            处理Virtual Base Class Subobject


    总结:

    能够这么觉得,并非在没有自己定义copy constructor的时候编译器就合成一个copy constructor,而是在没有着bitwise copy semantics当将合成 ,在运行default memberwise initialization什么时候。

    我没有参加这次行动中copy constructor当运行,此操作不会认为这是在copy constructor当完成。

    这是我的这一部分本书的理解。

  • 相关阅读:
    理解MySQL——索引与优化
    ArrayList vs LinkedList vs Vector
    Java集合框架的接口和类层次关系结构图
    Java集合的10个最常见问题
    Mysql 中的事件//定时任务
    Mysql中的函数
    Mysql中的触发器
    Mysql中的存储过程
    Oracle数据库表的一些宏处理
    Oracle查询和过滤重复数据
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4916280.html
Copyright © 2011-2022 走看看