这一章的时候,才明白什么是编译器的声明只会是一个默认的构造。这也解释了为什么同一似乎没有意义的界定,如果不还声明默认构造函数的意义。

Q:当编译器隐含定义了一个默认的构造函数。

答: 一个隐式声明的默认构造函数仅仅有在编译器须要的时候才隐式定义一个默认构造函数。仅仅有例如以下情况其才是必须的。

1、拥有虚成员函数的类。一个有虚成员函数的类一定会有一个non-trivial的构造函数。一个non-trivial的构造函数可能是用户定义的或者是编译器隐式定义的构造函数。而且它有责任为比如vptr的地址提供正确的初始化等。

2、带有Default Constructor 的 Member Class Object

3、带有Default Constructor的Base Class

4、带有一个Virtual Bass Class 的 Class

以上详情请见(深度探索C++对象模型)

Q:为什么编译器隐式声明Trivial构造函数即使他们从没有定义?

答:在一定条件下。编译器隐式声明一个默认构造函数但并不定义它。这种构造函数就是所谓的trivial。非常多c++程序猿对trivial成员函数的概念感到非常困惑。

当编译器知道某个函数不会被默认定义时到底是为什么这个编译器还要隐式的声明一个默认的构造函数呢?做这些有什么目的么?

首先第一件要牢记心中的事是隐式声明是概念上的,编译器并不会真正的在你的代码里面插入所谓的声明代码。更准确的说应该是编译器、连接器和程序表现的就像构造函数已经声明了。实际上,编译器仅仅是简单的在类的类型信息记录里面设置了一些bits用来表明它们所谓的类型有一个默认构造函数的声明。

如今我们回到最关键的问题上来吧,为什么要麻烦的有个隐式声明?毕竟C并不须要为它的struct或union提供这种机制。事实是隐式声明有一个契约似的规则。每个隐式声明就像合同里面的条款声明了一个确定的类怎么被使用。

当编译器隐式的声明这个特殊的成员函数,它授予某些授权给用户,相比之下,假设编译器不隐式声明成员函数,那就限制了用户对类的使用。考虑以下的代码:

struct Blocked
{
public:
Blocked(const Blocked&);
};

如今你肯定知道。由于copy-constructor的存在让编译器并不会隐式声明。

由于这个类没有隐式或显示的声明默认构造函数,你并不能像以下一样实例化一个类成员。

Blokced b; //error, no default constructor available
Blocked *p = new Blocked; //error

没有隐式声明的机制。程序猿不得不为每个须要实例化的类手动的加入构造函数,拷贝构造函数,赋值函数和析构函数。以下的POD类型证明了这个观点:

struct Date
{
int day, month, year;
};

编译器饮食声明了例如以下成员函数:

  • A trivial default constructor
  • A trivial copy constructor
  • A trivial assignment operator
  • A trivial destructor

这些声明能让你像以下一样使用Date:

Date d; //implicit declaration of default ctor and dtor allow this
Date * pdate= new Date; //same here
Date d2(d); //implicit copy ctor declaration allows this
*pdate=d2; //implicit assignment operator declaration allows this
delete pdate; //implicit dtor declaration allows this

trivial成员函数在C++编程里面是很重要的。为了让你明确它能为你省去多少麻烦,试着去显示声明它们:

struct Date
{
int day, month, year;
private:
~Date(); //declared but not defined
Date(const Date&); //ditto
};
Date d; //error, no default ctor
Date * pdate= new Date; //same error here
Date d2(d); //error, no accessible copy ctor

如今上面的代码就不能通过编译了。

c++ Constructor FAQ 继续的更多相关文章

  1. C#.NET常见问题(FAQ)-构造器constructor有什么用

    所谓的构造器constructor,就是声明类的时候定义一个public 类名的方法,这个方法不需要传递任何数据,这样的话在声明任何类的实例的时候都会无条件执行里面的方法   析构器只在程序销毁的时候 ...

  2. Ajax-ajax实例1-动态加载的 FAQ

    动态加载 FAQ 的过程主要是利用 XMLHttpRequest(以下简称 XHR)对象与服务端通信,根据用户单击的感兴趣问题动态将内容加载到页面中.在具体实现时,有两点要注意的内容. 1 .对每个问 ...

  3. AI框架类FAQ

    AI框架类FAQ 数据处理 问题:如何在训练过程中高效读取数量很大的数据集? 答复:当训练时使用的数据集数据量较大或者预处理逻辑复杂时,如果串行地进行数据读取,数据读取往往会成为训练效率的瓶颈.这种情 ...

  4. No-args constructor for class X does not exist. Register an InstanceCreator with Gson for this type to fix this problem.

    Gson解析JSON字符串时出现了下面的错误: No-args constructor for class X does not exist. Register an InstanceCreator ...

  5. 分析js中的constructor 和prototype

    在javascript的使用过程中,constructor 和prototype这两个概念是相当重要的,深入的理解这两个概念对理解js的一些核心概念非常的重要. 我们在定义函数的时候,函数定义的时候函 ...

  6. js中的constructor

    定义和用法 constructor 属性返回对创建此对象的 Date 函数的引用. 语法 object.constructor constructor属性不影响任何JavaScript的内部属性.in ...

  7. Java程序设计之Constructor

    插入段代码,下次回忆吧. 先新建一个Person类,代码如下: public class Person { private String name ; private int age; public ...

  8. prototype,__proto__,constructor

    proto属性: 所有对象都有此属性.但它不是规范里定义的属性,并不是所有JavaScript运行环境都支持.它指向对象的原型,也就是你说的继承链里的原型.通过Object.getPrototypeO ...

  9. Google软件构建工具Bazel FAQ

    Google软件构建工具Bazel FAQ 本文是我的翻译,原文在这里.欢迎转载,转载请注名本文作者和原始链接 注:如果想了解Bazel的原理,可以看看我之前翻译的Google Blaze原理及使用方 ...

随机推荐

  1. Oracle批量执行脚本文件

    以下是Oracle批量执行脚本文件的步骤和方法 1.创建脚本文件(xx.sql): 例如文件CreateTable Create table tb1( id varchar2(30), Name va ...

  2. url参数中出现+、空格、=、%、&、#等字符的解决办法

    url出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值,如何是好?解决办法将这些字符转化成服务器可以识别的字符,对应关系如下:URL字符转义 用其它 ...

  3. crm2011i创建nt类型字段

    using System;     using Microsoft.Xrm.Sdk;     using Microsoft.Xrm.Sdk.Messages;     using Microsoft ...

  4. Linux 的 Shell

    一个:Shell 概念 shell 这个词是不奇怪,意思是 "壳" 这是间OS 用户和芯层之间的相互作用,在linux系统.用户可以通过命令终端.使用shell 命令向下传达他们的 ...

  5. Team Foundation Server 2015使用教程--读取器tfs组的checkin权限修改

  6. css3 menu 手机菜单3

    首先看一下效果图; 效果1,主要是 scale(0) -->scale(1px);opacity:0;—>opacity: 1; 然后递归延迟 怕麻烦也可以自己写个for循环 .five ...

  7. (大数据工程师学习路径)第四步 SQL基础课程----select详解

    准备 在正式开始本内容之前,需要先从github下载相关代码,搭建好一个名为mysql_shiyan的数据库(有三张表:department,employee,project),并向其中插入数据. 具 ...

  8. unity与ios交替

    unity和ios的相互作用是更简单的.直接出口xcodeproject,这个大家都知道如何操作,如果需要二次开发ios码成unity,事实上,整合非常easy找到出口xcodeproject内iPh ...

  9. OR1200数据Cache介绍

    以下摘录<步骤吓得核心--软-core处理器的室内设计与分析>一本书 上一章剖析了ICache模块. 本章将剖析DCache模块.首先指出DCache模块相比ICache的特别之处.由于这 ...

  10. SQL随着子查询结果更新多个字段

    笔者:iamlasong 要求:表格内容需要改变,在临时表中内容的变化,使用SQL官方声明更新表若干领域. 假设更新一个字段,直接用字段名=子查询就能够了,多个字段更新,将字段在括号里并列写出就可以, ...