1. 默认初始化

如果定义变量时没有指定初值,则变量会被默认初始化,此时变量被赋予了“默认值”。

对于类类型的变量来说,初始化都是依靠构造函数来完成的。因此,即使定义某个类的变量(对象)时没有提供初始化式,我们也能通过类的默认构造函数来完成初始化。即,“默认值”由默认构造函数来决定(前提是该类有默认构造函数)。

对于内置类型的变量来说,当定义没有初始化式的变量时,系统有时会帮我们初始化变量。“默认值”由定义的位置决定:定义于任何函数体之外的变量被初始化为0;定义在函数体内部的变量默认值是未定义的,不会由系统自动初始化,虽然值是未定义的,但是仍然是有一个默认值的。即,“默认值”由定义的位置决定。

2. 针对const类型的默认值

const对象一旦创建后,其值就不能再改变,所以const对象必初始化(注意,必须由用户来决定怎么初始化从而给定默认值,而不是依靠系统)。

对于内置类型变量来说,我们自己初始化时,只有一种办法,就是提供值。即const内置类型变量无法默认初始化,系统也不会提供默认值。因此类似以下的代码语法上就是错的:

const int ival;   // 错误,ival没有初始化

对于类类型变量来说,我们通过构造函数来完成变量的初始化,这当然也包括了默认构造函数(必须是用户自定义的默认构造函数,而非系统合成的默认构造函数),因此可以在定义对象时,不提供初始化式:

const A object;   // 正确,通过默认构造函数来初始化

3. 合成的默认构造函数定义为delete的一种情况

1. 编译器创建的合成的默认构造函数按以下规则初始化类的数据成员:

-> 如果该数据成员有类内初始值,则在默认构函数中用类内初始值来初始化成员。

-> 如果该数据成员没有类内初始值,则在默认构造函数中该成员采取默认初始化。(更确切的说,是使用该成员的默认值)

2. 联系《primer 5th》page450-451

-> 如果在类中,有一个没有类内初始化器的const内置类型成员,则该成员没有办法初始化(因为const内置类型变量必须由用户自己来初始化,注意:const的内置类型变量是无法默认初始化的)。因为该成员没有办法自己初始化(通过以上1的两种方式初始化),因此该类的默认构造函数定义为删除(delete)。

-> 如果在类中,有一个没有类内初始化器的const类类型成员,且其类型没有显示定义默认构造函数(导致该const类类型成员也没有办法默认初始化),因此该类的默认构造函数定义为删除(delete)。

-> 如果在类中,有一个没有类内初始化器的类类型成员,且其类型没有定义默认构造函数(导致类类型成员也没有办法默认初始化),因此该类的默认构造函数被定义为删除(delete)。

有关此处的delete情况小结:

1. 首先需要明确内置类型变量是否可以默认初始化取决于变量位置,但无论如何,对于非const内置类型变量而言,一定会有一个默认值,即便其也许是未定义的;而对于类类型变量,如果要有默认值,必须要有默认构造函数,如果没有默认构造函数,其无法进行默认初始化。

2. 对于没有类内初始化器的内置类型成员来说,const使成员失去了拥有默认值的能力。

3. 对于没有类内初始化器的类类型成员来说,加const,必须有用户自定义的默认构造函数,才可以默认初始化,从而拥有默认值。不加const,那么只要有默认构造函数(隐式、显示均可)即可默认初始化,从而拥有默认值。

4. 本质含义

如果一个类有数据成员不能默认构造(更确切的说是无法拥有默认值)、拷贝、复制或销毁,则对应的成员函数将被定义为delete。

5. 与c++03标准区别

系统合成的构造函数定义为delete是c++11标准中提出的概念。

对于c++03标准而言,在有默认构造函数,且不是用户自定义的默认构造函数的情况下,那么我们默认隐式的默认构造函数一定是存在的。

合成的默认构造函数定义为delete的一种情况(针对C++11标准)的更多相关文章

  1. C++关于编译器合成的默认构造函数

    有两个常见的误解: 1.任何类如果没有定义默认构造函数,就会被合成出一个来. 2.编译器合成的默认构造函数会显式地设定类内每一个数据成员的默认值. 对于第一个误解,并不是任何类在没有显式定义默认构造函 ...

  2. C++ 合成默认构造函数的真相

    对于C++默认构造函数,我曾经有两点误解: 类如果没有定义任何的构造函数,那么编译器(一定会!)将为类定义一个合成的默认构造函数. 合成默认构造函数会初始化类中所有的数据成员. 第一个误解来自于我学习 ...

  3. C++中默认构造函数中数据成员的初始化

    构造函数的任务是初始化数据成员的,在类中,如果没有显示定义任何构造函数,编译器将为我们创建一个构造函数,称为合成的默认构造函数,合成的默认构造函数使用与变量初始化相同的规则来初始化成员.即当类中的数据 ...

  4. 【C++对象模型】构造函数语意学之一 默认构造函数

    默认构造函数,如果程序员没有为类定义构造函数,那么编译器会在[需要的时候]为类合成一个构造函数,而[需要的时候]分为程序员需要的时候和编译器需要的时候,程序员需要的时候应该由程序员来做工作,编译器需要 ...

  5. C++对象模型的那些事儿之三:默认构造函数

    前言 继前两篇总结了C++对象模型及其内存布局后,我们继续来探索一下C++对象的默认构造函数.对于C++的初学者来说,有如下两个误解: 任何class如果没有定义default constructor ...

  6. [C++11] 默认构造函数

    类通过一个特殊的构造函数来控制默认初始化过程.这个函数就是默认构造函数.默认构造函数无需不论什么实參. 我们能够显示的定义默认构造函数也能够让编译器为我们生成默认构造函数. 默认构造函数以例如以下规则 ...

  7. C++编译器会对没有构造函数的类生成默认构造函数吗?(有必要的时候才生成,要看情况。有反汇编验证)

    之前在上C++的课的时候,印象中有那么一句话:如果一个类没有任何构造函数,那么编译器会生成一个默认的构造函数 今天在看<深度探索C++对象模型>的第二章:“构造函数语意学”的时候发现之前听 ...

  8. C++编译器合成Default Constructor的4种情况

    笔记C++编译器为编译器需要合成Default Constructor的4种情况. 1,Class A内含Class B对象,Class A没有Default Constructor时会在编译时合成D ...

  9. C++对象模型——默认构造函数的合成

    最近在学习C++对象模型,看的书是侯捷老师的<深度探索C++对象模型>,发现自己以前对构造函数存在很多误解,作此笔记记录. 默认构造函数的误解 1.当程序猿定义了默认构造函数,编译器就会直 ...

随机推荐

  1. MySQL8.0的安装与配置(Windows 10)

    MySQL的下载 进入MySQL官网 https://www.mysql.com/ 选择 DOWNLOAD 到页面底部找到 MySQL Community Edition (GPL) 找到MySQL ...

  2. nginx 域名(虚拟)部署nodejs项目

    首先说下我的情况,Windows+mongodb开发的简单nodejs 小博客系统, 配置部署到centos7 nginx下,mongodb还是在我Windows机器下, 1.Linux安装node. ...

  3. so文件相关

    2018-08-31 今天尝试了一下编译so文件. 最开始是按照这个博主来操作的https://blog.csdn.net/tianshuai4317618/article/details/79073 ...

  4. js生成简单二维码

    js文件下载地址:https://download.csdn.net/download/weixin_38296752/10554485 一.引入qrcode.js文件 <script type ...

  5. maven mirror , profile , snapshot 和release

    1. settings.xml 配置的mirror <mirrors> <mirror> <id>Nexus</id> <name>nexu ...

  6. having 的用法

    聚合函数 where 后面不能直接使用聚合函数 处理函数 题目 编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱. 示例: +----+---------+ | Id | Email ...

  7. jvm层面锁优化+一般锁的优化策略

    偏向锁: 首先了解对象头MARK指针(对象头标记,32位): 存储GC标记,对象年龄,对象Hash,锁信息(锁记录的指针,偏向锁线程的ID) 大部分情况是没有竞争的,所以可以通过偏向来提高性能 所谓的 ...

  8. [C#.Net]KeyDown(KeyUp)和KeyPress的区别

    在keyDown事件里使用keyValue:在keyPress事件里使用keyChar. keyValue转换keyChar:(char)keyValue 验证只有数字和backSpace e.han ...

  9. 子数整数(P1151&NOIP水题测试(2017082301))

    题目链接:子数整数 水题,不解释,自己看代码: #include<bits/stdc++.h> using namespace std; int main(){ int k; scanf( ...

  10. SQL中datetime和timestamp的区别

    在开发一个简单的报名程序时,要求在每一条新插入的记录后面添加一个日期字段,方便日后查询和排序.于是立即百度,发现可以使用datetime或timestamp两种日期类型来实现.这对于爱纠结的我来说是不 ...