《深度探索C++对象模型》读书笔记(2)

default constructor仅在编译器需要它时,才会被合成出来。

通常来说,由编译器合成出来的default constructor是没啥用的(trivial),但有以下几种例外:

(1)带有“Default Constructor”的Member Class Object

如果一个class没有任何 constructor,但它内含一个member object,而后者有default constructor,那么编译器会在 constructor真正需要被调用时未此class合成一个“nontrivial”的default constructor. 为了避免合成出多个default constructor,解决方法是把合成的default constructor、copy constructor、destructor、assignment copy operator都以inline方式完成。一个inline函数有静态链 接(static linkage),不会被档案以外者看到。如果函数太复杂,不适合做成inline,就会合成出一 个explicit non-inline static实体。

根据准则“如果class A内含一个或一个以上的 member class objects,那么class A的每一个constructor必须调用每一个member classes的default constructor”,即便对于用户明确定义的default constructor,编译器也会对其进行扩张,在 explicit user code之前按“member objects在class中的声明次序”安插各个member所关联 的default constructor.

class Dcpey   { public:Dopey(); ... };
class Sneezy  { public:Sneezy(int); Sneezy(); ... };
class Bashful { public:Bashful(); ... };

class Snow_White {
public:
Dopey dopey;
Sneezy sneezy;
Bashful bashful;
// ...
private:
int mumble;
};

Snow_White::Snow_White() : sneezy(1024)
{
mumble = 2048;
}
// 编译器 扩张后的default constructor
Snow_White::Snow_White() : sneezy(1024)
{
// 插 入member class object
// 调用其constructor
dopey.Dopey::Dopey();
sneezy.Sneezy::Sneezy();
bashful.Bashful::Bashful();

// explicit user code
mumble = 2048;
}

(2)“带有Default Constructor”的 Base Class

如果一个没有任何constructors的class派生自一个“带有default constructor”的base class,那么这个derived class的default constructor会被视为 nontrivial,并因此需要被合成出来。

需要注意的是,编译器会将这些base class constructor 安插在member object之前。

时间: 2024-12-09 11:11:58

《深度探索C++对象模型》读书笔记(2)的相关文章

UNIX环境高级编程中的apue.h

/************** * *apueerror.h * *************/ #include <apue.h> #include <stdio.h> #include <errno.h> /* for definition of errno */ #include <stdarg.h> /* ISO C variable aruments */ static void err_doit(int, int, const char *, va

unix高级编程-UNIX环境高级编程 times() 疑问

问题描述 UNIX环境高级编程 times() 疑问 例程 int main(int argc, char *argv[]) { clock_t s_clk,e_clk; struct tms s_tms,e_tms; s_clk = times(&s_tms); system("ls /dev"); system("date"); sleep(1); e_clk = times(&e_tms); printf("e_clk %ld - s

ubuntu-最近在学习Unix 环境高级编程,配置环境时遇到了些问题

问题描述 最近在学习Unix 环境高级编程,配置环境时遇到了些问题 最近再看APUE(UNix 环境高级编程)的第三版,照着教程在中配置环境.也就是想要运行书中的源码,则要安装 libbsd-dev包,而每次安装这个包时,都如上报错,请问各位大虾,该怎么解决呢? 解决方案 你好, 类似的问题我也遇到过 ubuntu下apt-get install安装软件, 报"无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系",今天终于找到解决方法了. 一般出现这种情况的原

unix环境高级编程-UNIX环境高级编程源代码对应

问题描述 UNIX环境高级编程源代码对应 今天开始学习UNIX环境高级编程,书中的源代码下载到了,但是发现根本不是按章节来的,找起来是相当的费时间,有哪位大神用过后知道他们的对应关系么,比如1-1对应ls1.c这样,真是万分感激,造福大家啊!

Mac OS X 10.8 中编译APUE(Unix环境高级编程)的源代码过程_C 语言

最近在温习APUE(<unix环境高级编程>),以前都是在linux下搞,现在打算在自己机器弄下,于是google了下,把编译的事情搞定了,修改了一些教程的一些错误,比如下载链接之类的. 1.下载源文件,我这里是第二版,貌似第三版的英文版出来了... 复制代码 代码如下: wget http://www.apuebook.com/src.2e.tar.gz 2.解压 复制代码 代码如下: tar zxf src.2e.tar.gz 3.修改些东西 复制代码 代码如下: cd apue.2e/

UNIX环境高级编程---标准I/O库

前言:我想大家学习C语言接触过的第一个函数应该是printf,但是我们真正理解它了吗?最近看Linux以及网络编程这块,我觉得I/O这块很难理解.以前从来没认识到Unix I/O和C标准库I/O函数压根不是一码事.Unix I/O也叫低级I/O,也叫Unbuffered I/O,是操作系统内核部分,也是系统调用:而C标准I/O函数相对也成Buffered I/O,高级I/O,一般是为了效率考虑对这些系统调用的封装.以前使用getchar()经常为输入完后的回车而出错.那是不理解标准I/O实现时的

UNIX环境高级编程:线程同步之互斥锁、读写锁和条件变量

一.使用互斥锁 1.初始化互斥量 pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER;//静态初始化互斥量 int pthread_mutex_init(pthread_mutex_t*mutex,pthread_mutexattr_t*attr);//动态初始化互斥量 int pthread_mutex_destory(pthread_mutex_t*mutex);//撤销互斥量 不能拷贝互斥量变量,但可以拷贝指向互斥量的指针,这样就可以使多个函数

UNIX环境高级编程:线程属性

pthread_attr_t 的缺省属性值 1.初始化一个线程对象的属性 int pthread_attr_init(pthread_attr_t *attr); 返回值:若是成功返回0,否则返回错误的编号 形  参: attr       指向一个线程属性的指针 说  明:Posix线程中的线程属性pthread_attr_t主要包括scope属性.detach属性.堆栈地址.堆栈大小.优先级. pthread_attr_init实现时为属性对象分配了动态内存空间. 线程属性结构如下: typ

UNIX环境高级编程:线程属性之并发度

并发度控制着用户级线程可以映射的内核线程或进程的数目.如果操作系统的实现在内核级的线程和用户级的线程之间保持一对一的映射,那么改变并发度并不会有什么效果,因为所有的用户级线程都可能被调度到.但是,如果操作系统的实现让用户级线程到内核级线程或进程之间的映射关系是多对一的话,那么在给定时间内增加可运行的用户级线程数,可能会改善性能. pthread_setconcurrency函数可以用于提示系统,表明希望的并发度. #include <pthread.h> int pthread_getconc

UNIX环境高级编程:system V消息队列

unix早期通信机制中的信号能够传送的信息量有限,管道则只能传送无格式字节流,这远远是不够的. 消息队列(也叫报文队列)客服了这些缺点: 消息队列就是一个消息的链表. 可以把消息看作一个记录,具有特定的格式. 进程可以按照一定的规则向消息队列中添加新消息:另一些进程可以从消息队列中读走消息. 消息队列是随内核持续的,只有内核重启或人工删除时,该消息队列才会被删除. system V消息队列使用消息队列标识符标识.具有足够特权的任何进程都可以往一个给定队列放置一个消息,具有足够特权的任何进程都可以