深入探索C++对象模型-语义
有三种情况,这将是一个object的内容,以及一class object早期值:
- class X { ... };
- X x;
- X xx = x; // 情况1,赋值对象
- extern void foo( X x);
- void bar()
- {
- X xx;
- foo( xx ); // 情况2,作为參数
- }
- X foo_bar()
- {
- X xx;
- return xx; // 情况3。作为返回值
- }
Default Memberwise Initalization
假设class 没有提供一个explicit copy constructor又当怎样?当class object 以 “同样class的还有一个object”作为初值时,其内是以所谓的default memberwise initalization手法完毕的。也就是把每个内建的或派生的data member的值,从某个object拷贝一份到还有一个object身上。
只是它不会拷贝当中的member class object, 而是以递归的方式实行memberwise
initalization.
样例:
- class String
- {
- public:
- //..没有explicit copy constructor
- private:
- char *str;
- int len;
- };
- class Word
- {
- public:
- //..没有explicit copy constructor
- private:
- int _occurs;
- String _word; //String object成为class word的一个member. 此处以递归的方式实行memberwise initalization.
- // Word 是否合成 copy constructor 取决于 bitwise copy semantics.
- //此样例不合成copy constructor 编译器会自己主动复制每个数据成员
- };
指出一个错误概念:“假设一个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时
结论:假设是自己定义复制构造函数时,须要自己把每个数据成员复制;假设是没有自己定义复制构造函数。不管是合成或非合成,编译器都会自己主动复制每个数据成员。复制构造函数的用途是:假设构造函数中存在动态内存分配,则必须定义复制构造函数,否则会出现“指针悬挂问题”。
- class A
- {
- private:
- int *p;
- public:
- A()
- {
- p = new int(3);
- }
- };
在这样的情况下,复制对象。会造成两个对象的成员指向同一地址。
又一次设定Virtual Table的指针
样例:
- class ZooAninal
- {
- public:
- ZooAnimal();
- virtual ~ZooAnimal();
- virtual void animate();
- virtual void draw();
- };
- class Bear : public ZooAnimal()
- {
- public:
- Bear();
- void animate();
- void draw();
- virtual void dance();
- };
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当完成。
这是我的这一部分本书的理解。
深入探索C++对象模型-语义的更多相关文章
- 拾遗与填坑《深度探索C++对象模型》3.3节
<深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...
- 深度探索C++对象模型
深度探索C++对象模型 什么是C++对象模型: 语言中直接支持面向对象程序设计的部分. 对于各个支持的底层实现机制. 抽象性与实际性之间找出平衡点, 需要知识, 经验以及许多思考. 导读 这本书是C+ ...
- 读书笔记《深度探索c++对象模型》 概述
<深度探索c++对象模型>这本书是我工作一段时间后想更深入了解C++的底层实现知识,如内存布局.模型.内存大小.继承.虚函数表等而阅读的:此外在很多面试或者工作中,对底层的知识的足够了解也 ...
- 柔性数组-读《深度探索C++对象模型》有感 (转载)
最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...
- 柔性数组-读《深度探索C++对象模型》有感
最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...
- [读书系列] 深度探索C++对象模型 初读
2012年底-2014年初这段时间主要用C++做手游开发,时隔3年,重新拿起<深度探索C++对象模型>这本书,感觉生疏了很多,如果按前阵子的生疏度来说,现在不借助Visual Studio ...
- 拾遗与填坑《深度探索C++对象模型》3.2节
<深度探索C++对象模型>是一本好书,该书作者也是<C++ Primer>的作者,一位绝对的C++大师.诚然该书中也有多多少少的错误一直为人所诟病,但这仍然不妨碍称其为一本好书 ...
- 《深度探索C++对象模型》读书笔记(一)
前言 今年中下旬就要找工作了,我计划从现在就开始准备一些面试中会问到的基础知识,包括C++.操作系统.计算机网络.算法和数据结构等.C++就先从这本<深度探索C++对象模型>开始.不同于& ...
- C++的黑科技(深入探索C++对象模型)
周二面了腾讯,之前只投了TST内推,貌似就是TST面试了 其中有一个问题,“如何产生一个不能被继承的类”,这道题我反反复复只想到,将父类的构造函数私有,让子类不能调用,最后归结出一个单例模式,但面试官 ...
随机推荐
- uva 10581 - Partitioning for fun and profit(记忆化搜索+数论)
题目链接:uva 10581 - Partitioning for fun and profit 题目大意:给定m,n,k,将m分解成n份,然后依照每份的个数排定字典序,而且划分时要求ai−1≤ai, ...
- HDU 1142 A Walk Through the Forest(dijkstra+记忆化DFS)
题意: 给你一个图,找最短路.但是有个非一般的的条件:如果a,b之间有路,且你选择要走这条路,那么必须保证a到终点的所有路都小于b到终点的一条路.问满足这样的路径条数 有多少,噶呜~~题意是搜了解题报 ...
- CentOS下yum使用代理的设置
export后好像没用? 问题描述: CentOS yum时出现“Could not retrieve mirrorlist http://mirrorlist.centos.org/?release ...
- C# split字符串 依据1个或多个空格
实例场景.对于字符串:"AAAA AAA BBBB BBB BBB CCCCCCCC". 1. 分隔为 "AAAA AAA" . & ...
- Delphi的没落有三个原因(比较贴切)
Delphi的没落有三个原因:1,Object pascal并没有像C/C++那样成为业内标准. 如果你使用C或C++写程序,可以在任何地方进行编译,例如Windows.Linux.手机,甚至是单片机 ...
- Pods was rejected as an implicit dependency for 'libPods.a' because its architectures 'x86_64' didn
引入cocoaPods后.第一次编译,或者运行update后 可能报这个错误: Pods was rejected as an implicit dependency for 'libPods.a' ...
- block存储区域——怎样验证block在栈上,还是堆上
Block存储区域 首先,须要引入三个名词: ● _NSConcretStackBlock ● _NSConcretGlobalBlock ● _NSConcretMallocBlock 正如它们名字 ...
- hdu1081(最大子矩阵)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1081 分析:a[i][j]代表第i行,前j个数据的和:那么由a[i][j]可得sum[k][long] ...
- sqlserver安全加固
sqlserver2012安装好以后必要的安全加固,不然非常多DBA的信息普通账户登录后都能够读取到. --use [master] --GO --DENY VIEW SERVER STATE ...
- Ubuntu——grub rescue 主引导修复
长期使用windows 和 ubuntu 人双系统,很可能遇到沉重的一个系统,或以其他方式加盟分区,导致系统重新启动时 : GRUB loading error:unknow filesystem g ...