构造函数的那些事

构造函数:是一种特殊的方法,主要用来在创建对象时初始化对象,即为对象成员变量赋初始值。--百度百科

析构函数和构造函数相对应,它的功能是释放对象的内存空间。为了便于分析和理解,博客内容加入了析构函数,并且将初始化列表单独拿出来分析。博客结构:

详细内容如下:

一 
构造函数:

1
构造函数是干什么的?

当一个类对象被创建时,编译系统后需要为对象分配内存空间,C++中这个工作是由构造函数来完成。需要注意的是,初始化不等于赋值,初始化即分配空间,赋值是向内存空间插入数据。

2构造函数都有那些类型?

默认构造函数:即如果没有显示的写出构造函数,系统将会自动生成一个构造函数,这个构造函数没有参数,函数体为空,它什么都不做;

一般构造函数(或者叫做重载构造函数):一个类构造函数可以有多个构造函数,参数的不同,就可以形成函数的重载,创建对象时根据参数来判断具体调用哪个构造函数;

复制构造函数:当类对象本身的引用作为构造函数的参数时,构造函数会复制出一个新的对象,已存在的对象的数据成员的值会被复制到新创建的对象中。

3
构造函数有那些特点?

构造函数的命名必须和类名完全相同;构造函数用于完成对象初始化,所以它没有返回值,不能用任何数据类型来修饰它;构造函数不能被显示调用(父类构造函数带参数除外),只能在创建对象时由编译器自动调用。如果一个类只定义了私有的构造函数,将无法通过new关键字创建其对象。构造函数不可以是虚函数。

二析构函数:

析构函数和构造函数向对应,它是为了释放对象内存而存在的。它不能被显式调用,只能在删除对象时由编译器调用;它没有返回值,所以不能用任何(包括void)修饰;没有参数(不能重载)。

三构造函数的初始化列表:

1
为什么使用初始化列表?构造函数初始化类的成员有两种方式,一是使用初始化列表,二是在构造函数体内进行赋值操作。这两种方式有什么区别?使用初始化列表,那么构造函数在创建对象时分配内存空间,并且直接进行赋值;如果是在函数体内赋值,那么首先要调用构造函数分配内存,然后调用函数体进行赋值操作,也就是赋值操作需要比初始化列表多一个步骤,对于成员变量较少的类没有区别,但是对于有大量的成员变量的类,创建对象就是一种灾难。

2 初始化列表的一般格式:

Class A
{
    Private:
<span style="white-space:pre">	</span>int a;
<span style="white-space:pre">	</span>Int b;
    Public:
<span style="white-space:pre">	</span>A(int _a,int_b):a(_a),b(_b) {}
}

对于无默认构造函数的继承关系:

Class person
{
    Public:
<span style="white-space:pre">	</span>Person(string name,string sex):_name(name),_sex(sex)  {}
    Private:
<span style="white-space:pre">	</span>String _name;
<span style="white-space:pre">	</span>String _sex;
}
Class man :public person
{
    Public :
<span style="white-space:pre">	</span>Man(string name ,string sex, string age):person(name,sex),_age(age)
<span style="white-space:pre">	</span>{}
    Private:
<span style="white-space:pre">	</span>String _age;
}

3 那些对象初始化必须要使用初始化列表?

(1) const常量 const常量不能被赋值,只能初始化,所以需要使用初始化列表。

Class A
{
    Public :
<span style="white-space:pre">	</span>A(int b):_b(b) {}        //正确
<span style="white-space:pre">	</span>A(int b) {_b =b;}       //错误,常量不能赋值。
    Private:
<span style="white-space:pre">	</span>Const int _b;
}

注意,上述两个构造函数不能共存。

(2) 含有自定义数据类型(类)对象的初始化

Class Person
{
    ;
}
Class Man
{
    Public :
<span style="white-space:pre">	</span>Man(Person & sa): _sa(sa) {}
    Private:
<span style="white-space:pre">	</span>Person _sa;
}

(3) 引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写到初始化列表中。

Class A
{
   Public :
<span style="white-space:pre">	</span>A(int r):_r(r) {}
   Private:
<span style="white-space:pre">	</span>Int  &_r;
}

构造函数内容繁琐,很多细节需要反复去验证。

以上为个人理解,如有错误,敬请指正。

时间: 2024-10-01 00:53:31

构造函数的那些事的相关文章

类 的重载(Overloads)与隐藏(Shadows)

我在上篇文章中讲解了类 的继承和重写,如果想要在派生类中重写基类了方法或函数,那首先基类必须要有用 Overridable 关键字的公开声明的方法或函数,这样,基类的派生类才能用 Overrides 关键字来重写基类带有 Overridable 关键字的公开方法或函数. 重载是什么意思呢? 重载(Overloads): 就是我们可以用同样的名称,在派生类中用不同的参数列表来创建多个方法和属性,在调用时就可以适应不同参数类型的要求. 呵呵...那好,我们来看一下,这样的写法会有什么结果: Modu

javascript的oop——&gt;&gt;&gt; [__proto__ 与 prototype/原型链/原型属性与原型方法/for-in循环]

  前  言  OOP  javascript的oop中的__proto__  与  prototype/原型链/原型属性与原型方法/for-in循环 1  __proto__  与  prototype/原型链   1.prototype(函数的原型):函数才有prototype.prototype是一个对象,指向了当前构造函数的引用地址呢.                       2.__proto__(对象的原型对象):所有对象都要__proto__属性.当用构造函数实例化(new)一

TypeScript - Classes

简介 JavaScript语言基于函数和原型链继承机制的方式构建可重用的组件.这对于OO方面编程来说显得比较笨拙.在下一代的JavaScript标准ECMAScript 6为我们提供了基于class base的OO设计方式.在TypeScript中我们也允许使用这种方式,TypeScript将编译为目前大多数浏览器能允许的普通Javascript代码,所以我们不用在等待ECMAScript 6的到来了. 类 我们先看一个关于class-base的实例: class Greeter { greet

JavaScript面向对象(二)——成员属性、静态属性、原型属性与JS原型链

前  言 上一篇博客(https://www.cnblogs.com/qdjianghao/p/10177360.html )中,我们介绍了JS中的面向对象,并详细的解释了this的指向问题.本篇博客,我们继续来学习JS的面向对象.来深入理解一下JavaScript OOP中的成员属性/方法.静态属性/方法.原型属性/方法,并且一起来探讨一下JS中的原型与原型链. 一 成员属性与成员方法 在构造函数中,通过this.属性声明.或者实例化出对象后,通过"对象.属性"追加的.都属于成员属性

C++构造函数:初始化的那些事

C++构造函数:初始化的那些事 说起C++的构造函数,大家绝不会陌生,似乎老生常谈,我一度也这么认为,但是有时概念的不清晰也许会使我们陷入莫名的困惑,下面我们就来初步的探索一下C++构造函数中那些有关初始化的事.(vs2010) 1.默认的初始化 想必大家都知道C++会在我们没有提供任何构造函数的情况下为我们提供默认的缺省的构造函数,而构造函数的作用无非两样,第一步分配空间,初始化成员变量.换句话说,当我们调用构造函数时,发生了下面两件事情: (1) 为对象非配足够的内存块,若是new关键字产生

构造函数与虚构函数

1.构造函数和析构函数为什么没有返回值? 构造函数和析构函数是两个非常特殊的函数:它们没有返回值.这与返回值为void的函数显然不同,后者虽然也不返回任何值,但还可以让它做点别的事情,而构造函数和析构函数则不允许. 在程序中创建和消除一个对象的行为非常特殊,就像出生和死亡,而且总是由编译器来调用这些函数以确保它们被执行.如果它们有返回值,要么编译器必须知道如何处理返回值,要么就只能由客户程序员自己来显式的调用构造函数与析构函数,这样一来,安全性就被破坏了.另外,析构函数不带任何参数,因为析构不需

关于c++的运算符重载那些事

搞c++有一段时间了,今天突然要重载一个运算符,发现自己有点忘了,遂查查资料做一下c++运算符重载的小总结. 一.何为运算符重载 运算符的重载是c++语言特有的,java什么的是没有运算符重载的,所以运算符重载在笔试面试中有可能成为c++的高频考点.运算符重载就是重新定义运算符的意义,如常用的+,-,×,÷都是可以重载的.运算符重载使用的是关键字operator,表现形式是:                                                            

手机那点事!已有高人把常见的不常见的坑都给找出来了,我就随便转一下了

mobileTech A useful tools or tips list for mobile web application developing 这个项目收集移动端开发所需要的一些资源与小技巧 工具类网站 HTML5 与 CSS3 技术应用评估 各种奇妙的hack 几乎所有设备的屏幕尺寸与像素密度表 移动设备参数表 ios端移动设备参数速查 浏览器兼容表 移动设备查询器 移动设备适配库 移动设备适配库2 viewport与设备尺寸在线检测器 html5 移动端兼容性速查 在线转换字体 c

面向对象编程-基础(工厂、构造函数、原型、混合、动态等模式)

本文参考:js高级程序设计 第三版这篇文章我啃了大半天写的,是很烦,没有毅力看下去的注定还是不会(1).工厂模式:封装一个函数createPerson,这个函数可以创造一个人对象,包含三个属性和一个方法,然后利用这个函数分别创建了2个对象p1,p2. function createPerson(name,age,job){ var p=new Object(); p.name=name; p.age=age; p.job=job; p.showName=function(){ alert(thi