隐藏在default construct后面的是什么

C++新手很容易陷入两个认识上的误区:

1.任何类如果不显示的定义一个构造函数那么编译器就会构造出一个默认构造函数。

2.默认构造函数负责类的所有数据成员的初始化,显然不是这样的。

为什么不是这样的,下面来进行详细的说明和解答,下面会说明在什么情况下一种有用的构造函数会被编译器构造出来。

类的默认构造函数:default construct,一个c++类什么时候需要构造出一个默认的构造函数,答案是在编译器需要的时候,这里指的是编译器需要的时候,举个例子。

Class Foo

{

Public :

Foo * pNext;

char * str;

}

在这个例子里面对象成员的初始化不应该交给编译器来做,因为对于类的对象的初始化是程序需要考虑的事情,当然也需要交由Foo类的构造者来完成。比如

Foo :: Foo()

{

Str = 0;

pNext =NULL;

}

  1. 默认构造函数由编译器声明分为多种的情形,其中情形一位:当一个类之中含有了一个已经存在默认构造函数其他类的对象时,那么这个类就需要声明出默认的构造函数来完成类的成员对象的初始化。

Class Foo

{

Public :

Foo ();

Foo(int);

}

Class Bar

{

Public :

Foo foo;

Char * str;

}

此时就需要类的构造函数来进行Foo类对象的初始化,这里再次分为两种情况,第一种就是Bar类的构造着不进行显示的构造函数编写,那么就会由编译器来进行默认构造函数的构建就像下面这样,编译器默认的构造函数只负责foo对象的初始胡他并不会负责str的初始化。

Bar::bar()

{

Foo.Foo::Foo();

}

当Bar类的构造着显示的声明了一个构造函数的时候编译器在用户代码之前也会负责进行Foo对象的初始化就像下面一样。

用户代码:Bar::bar()

{

Str = 0;

}

编译器添加了初始化代码之后的结构:

Bar::bar()

{

//在用户代码之前编译器必须负责构造foo对象

// Foo.Foo::Foo();

Str = 0;

}

需要注意的是当一个类包含了多个其他类的成员对象的时候需要按照顺序进行类的对象初始化向下面的例子。

Class point {public : point()}

Class line  {public: line(); line(int)}

Class shape {public: shape()……}

Class test

{

Public :

Point m_point;

Line m_line;

Shape m_shape;

Private :

Int m_ival;

}

显示的构造函数,用户代码:test::test():line(1024)

{

M_ival = 0;

}

编译器代码:

Test:test():line(1024)

{

//首先需要对对象point和shape进行初始化,这些操作都将由编译器完成

//Point:point::point();

Line:line::line(1024);

//Shape.shape::shape();

M_ival = 0;

}

2.带有默认构造函数的基类

带有默认构造函数的基类,对于这种类型的构造函数和之前提到过的相似,因为派生类对象在构造之前必须要先构造出基类的构造函数,所以编译器在编译阶段会进行代码扩展,将基类的默认构造函数添加到派生类的构造函数代码中。

3.基类含有vritual function 的派生类对象

因为这种类型的类编译器在编译阶段需要产生一个虚表vtab和一个指向vtab的虚表指针vptr,vptr内含虚表的地址值。出于这种考虑如果用户不声明一个构造函数,那么编译器必须合成出一个默认的构造函数来进行每一个对象的虚表指针vptr的初始化。

4.含有virtual class 的派生类

和上面的道理一样,编译器也必须产生出一个指向虚基类的指针进行虚基类成员的操作,这个阶段就发生在默认构造函数中。

时间: 2024-08-10 23:16:12

隐藏在default construct后面的是什么的相关文章

Cannot construct instance of `com.jty.entities.Dept` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

使用RestTemplate对象访问请求出错 @GetMapping(value = "/consumer/dept/get/{id}") public Dept get(@PathVariable Long id){ return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class); } Cannot construct instance of com.jty.entities

面向对象5——封装和隐藏

.面向对象三大特性:封装.继承.多态 封装 1.定义 .将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息:通过该类所提供的方法来实现对内部信息的操作和访问 2.目的 .隐藏类的实现细节 .让使用者只能通过实现预定的方法来访问数据,从而可以在该方法中加入逻辑控制,限制对成员变量的不合理访问 .可进行数据检查,从而奥正对象信息的完整性 .便于修改,提高代码的可维护性 3.实现 .将对象的成员变量和实现隐藏起来,不允许外部直接访问 .把方法暴露出来,让方法控制这些成员变量进行安全访问

【ThinkingInC++】38、选择重载还是默认参数

头文件 /** * 书本:[ThinkingInC++] * 功能:选择重载还是默认参数,头文件 * 时间:2014年9月6日14:54:28 * 作者:cutter_point */ #ifndef MEM_H_INCLUDED #define MEM_H_INCLUDED typedef unsigned char byte; class Mem { byte* mem; int size; void ensureMinSize(int minSize); //成员函数来增加内存块的大小 p

c++11之右值引用和std::move

这两个特性是c++11里比较有性能提升意义的.个人认为这两个特性也体现了c++对性能提升的极限追求. 通过改写经典c++面试题mystring来体会 move不能减少临时变量的产生,但是可以减少内存的维护量 代码 //右值引用 /* 左值对象:持久存在的对象,具有名字,可以对其去地址 右值对象:临时对象,表达式结束后它就没了,不能对它取地址,它也没有名字~ 右值引用类型:引用右值的类型,用&&来表示 */ /*****************************************

Java应用程序实现屏幕的"拍照"

有时候,在Java应用程序开发中,如:远程监控或远程教学,常常需要对计算机的屏幕进行截取,由于屏幕截取是比较接近操作系统的操作,在Windows操作系统下,该操作几乎成了VC.VB等的专利,事实上,使用Java JDK1.4 的Robot对象,来完成"屏幕截取操作,更加简单.Java JDK1.4 的Robot对象,该对象可以完成对"屏幕"像素的拷贝,完成屏幕图像截取操作.Java应用程序中可以直接调用此对象,完成对特定应用程序的屏幕截取,如果将此功能配合网络,便可以轻而易举

第15课 用户界面与业务逻辑的分离

1. 界面与逻辑 (1)用户界面模块(UI):接受用户输入及呈现数据 (2)业务逻辑模块(Business Logic):根据用户需求处理数据 2.用户界面与业务逻辑的交互 2.1 基本设计原则 (1)功能模块之间需要进行解耦 (2)核心思想:强内聚.弱耦合 ①每个模块应该只实现单一的功能 ②模块内部的子模块只为整体的单一功能而存在 ③模块之间通过约定好的接口进行交互 2.2 工程开发中的“接口” (1)广义:接口是一种契约(协议.语法.格式等) (2)狭义: ①面向过程:接口是一组预定义的函数

类中函数

[1]空类为什么可以创建对象呢? 示例代码如下: 1 class Test 2 { 3 }; 4 void main() 5 { 6 Test t1; 7 cout<<sizeof(Test)<<endl; //1 8 } 让我们先看看这个例子.既然都没有构造函数,怎么实现对象t1的构建呢? 哦,经过大脑的回旋式搜索,忆得有一本书上说过,当用户定义一个空类(如上)时,编译器就会为这个类默认生成六个方法. 既然这是编译器完成的工作,那我们只要知道是那些方法就好了,其余就学习编译器的结

和Keyle一起学StrangeIoc &ndash; Extensions

Strange: the IoC framework for Unity Extensions You may have heard that Strange is a Dependency Injection framework. I'm a little uncomfortable with that description. Sure, Strange offers DI and it's a great use, but the core of the framework - as I'

Web QQ 协议 登录加密算法 —— VC++实现

BOOL ToHexStr(const CHAR * lpStr, int nSrcLen, CHAR * lpHex, int nDestLen) { const CHAR cHexTable[] = "0123456789ABCDEF"; if (lpStr == NULL || nSrcLen <= 0 || lpHex == NULL || nDestLen <= 0) return FALSE; if (nDestLen <= nSrcLen * 2) re