构造函数是一种特殊的成员函数,在创建对象时自动执行,主要用来进行初始化工作,例如对 private 属性的成员变量赋值。

对成员变量的初始化,除了在构造函数的函数体中一一赋值,还可以采用参数初始化表。请看下面的代码:

class Student{
private:
char *name;
int age;
float score;
public:
Student(char *, int, float);
void say();
};
//在构造函数中采用参数初始化表
Student::Student(char *name1, int age1, float score1):name(name1), age(age1), score(score1){}
void Student::say(){
cout<<name<<"的年龄是 "<<age<<",成绩是 "<<score<<endl;
}

如本例所示,在定义带参构造函数 Student(char *name1, int age1, float score1) 时,不再是在函数体中对成员变量一一赋值,其函数体为空。在函数首部与函数体之间增添了一个冒并加上 name(name1), age(age1), score(score1) 语句,这个语句的意思相当于函数体内部的 name = name1; age = age1; score = score1; 语句。

参数初始化表还有一个很重要的作用,那就是为 const 成员变量初始化。例如:

class Array{
public:
Array(){
length = ; //compile error
num = NULL;
};
private:
const int length;
int * num;
};

在本例中Array类声明了两个成员变量,length 和 num 指针,需要注意的是 length 加了 const 关键字修饰。此时默认构造函数再为 length 赋值为 0,这是无法通过编译的

初始化 const 成员变量的唯一方法只有利用参数初始化表。例如:

class Array{
public:
Array(): length(){
num = NULL;
};
private:
const int length;
int * num;
};

需要注意的是:参数初始化顺序与初始化表列出的变量的顺序无关,参数初始化顺序只与成员变量在类中声明的顺序有关。

C++析构函数

创建对象时系统会自动调用构造函数进行初始化工作,同样,销毁对象时系统也会自动调用一个函数来进行清理工作(例如回收创建对象时消耗的各种资源),这个函数被称为析构函数。

析构函数(Destructor)也是一种特殊的成员函数,没有返回值,不需要用户调用,而是在销毁对象时自动执行。与构造函数不同的是,析构函数的名字是在类名前面加一个”~“符号。

注意:析构函数没有参数不能被重载因此一个类只能有一个析构函数。如果用户没有定义,那么编译器会自动生成。

析构函数举例:

#include <iostream>
using namespace std;
class Student{
private:
char *name;
int age;
float score;
public:
//构造函数
Student(char *, int, float);
//析构函数
~Student();
//普通成员函数
void say();
};
Student::Student(char *name1, int age1, float score1):name(name1), age(age1), score(score1){}
Student::~Student(){
cout<<name<<"再见"<<endl;
}
void Student::say(){
cout<<name<<"的年龄是 "<<age<<",成绩是 "<<score<<endl;
}
int main(){
Student stu1("小明", , 90.5f);
stu1.say(); Student stu2("李磊", , );
stu2.say(); Student stu3("王爽", , 80.5f);
stu3.say();
cout<<"main 函数即将运行结束"<<endl; return ;
}

可以看出,析构函数在 main 函数运行结束前被执行,并且调用顺序和构造函数正好相反,为了方便记忆,我们可以将之理解为一个栈,先入后出

析构函数在对象被销毁前执行;要知道析构函数什么时候被调用,就要先知道对象什么时候被销毁。

对象可以认为是通过类这种数据类型定义的变量,它的很多特性和普通变量是一样的,例如作用域、生命周期等。由此可以推断,对象这种变量的销毁时机和普通变量是一样的。

总结起来,有下面几种情况:
1) 如果在一个函数中定义了一个对象(auto 局部变量),当这个函数运行结束时,对象就会被销毁,在对象被销毁前自动执行析构函数。

2) static 局部对象在函数调用结束时并不销毁,因此也不调用析构函数,只有在程序结束时(如 main 函数结束或调用 exit 函数)才调用 static 局部对象的析构函数。

3) 如果定义了一个全局对象,也只有在程序结束时才会调用该全局对象的析构函数。

4) 如果用 new 运算符动态地建立了一个对象,当用 delete 运算符释放该对象时,先调用该对象的析构函数

注意:析构函数的作用并不是删除对象,而是在撤销对象占用的内存之前完成一些清理工作,使这部分内存可以分配给新对象使用。

C++学习8 构造函数的参数初始化表的更多相关文章

  1. 2.8 C++参数初始化表

    参考:http://www.weixueyuan.net/view/6340.html 总结: 参数初始化表可以为任何数据成员进行初始化. 初始化const成员变量的唯一方法只有利用参数初始化表. 通 ...

  2. 构造函数和初始化表、this指针与常函数、析构函数、拷贝构造与拷贝赋值(day05)

    十四 构造函数和初始化表 ... 初始化表 )语法形式 class 类名{ 类名(形参表):成员变量1(初值),...{} }; )必须要使用初始化表的场景 -->如果有类 类型的成员变量,而该 ...

  3. 类的定义与实例化、构造函数和初始化表(day04)

    十三 类的定义与实例化 类的一般形式 class/struct 类名:继承表{ 访问控制限定符: 类名(形参表):初始化表{}//构造函数 ~类名(void){}//析构函数 返回类型 函数名(形参表 ...

  4. C#深入学习笔记 - 可空类型与构造函数默认参数

    在实际开发中或许可能会遇到某个属性需要提供一个默认参数,如果该参数是引用类型的话,可以通过 使用 null 来表示未知的值,但如果是int或 其他值类型的话就有点不好办了,因为如果需要一个int或fl ...

  5. 深度学习 吴恩达深度学习课程2第三周 tensorflow实践 参数初始化的影响

    博主 撸的  该节 代码 地址 :https://github.com/LemonTree1994/machine-learning/blob/master/%E5%90%B4%E6%81%A9%E8 ...

  6. keras模块学习之-参数初始化与对象调用-笔记

    本笔记由博客园-圆柱模板 博主整理笔记发布,转载需注明,谢谢合作! 参数初始化(Initializations) 这个模块的作用是在添加layer时调用init进行这一层的权重初始化,有两种初始化方法 ...

  7. 学习C++ -> 构造函数与析构函数

    学习C++ -> 构造函数与析构函数 一.构造函数的介绍    1. 构造函数的作用        构造函数主要用来在创建对象时完成对对象属性的一些初始化等操作, 当创建对象时, 对象会自动调用 ...

  8. Django学习笔记(6)——Form表单

    知识储备:HTML表单form学习 表单,在前端页面中属于最常见的一个东西了.基本上网站信息的提交都用到了表单,所以下面来学习Django中优雅的表单系统:Form 表单的主要作用是在网页上提供一个图 ...

  9. jQuery form插件的使用--用 formData 参数校验表单,验证后提交(简单验证).

    Form Plugin API 里提供了很多有用的方法可以让你轻松的处理表单里的数据和表单的提交过程. 测试环境:部署到Tomcat中的web项目. 一.引入依赖js <script src=& ...

随机推荐

  1. request.getParameter与request.getAttribute()

    这里就request为例,不去考虑session. request对象是javax.servlet.http.HttpServletRequest接口的一个实例,request表示调用JSP页面的请求 ...

  2. linux node&& npm 安装方式

    1.  编译好的文件 简单说就是解压后,在bin文件夹中已经存在node以及npm,如果你进入到对应文件的中执行命令行一点问题都没有,不过不是全局的,所以将这个设置为全局就好了. cd node-v0 ...

  3. 安卓中Activity的onStart()和onResume()的区别是什么

    知道Activity的四种状态:Active/Runing 一个新 Activity 启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态. Paused 当 Activ ...

  4. asp.net生成PDF文件 (1)

    asp.net生成PDF文件 (1) 这个是例子是网上淘来的,哈哈,很有用的! 首先要到网上下载itextsharp.dll,然后添加引用,主程序如下: 1 2 3 4 5 6 7 8 9 10 11 ...

  5. 详解Android首选项框架ListPreference

    详解Android首选项框架ListPreference 原文地址 探索首选项框架 在深入探讨Android的首选项框架之前,首先构想一个需要使用首选项的场景,然后分析如何实现这一场景.假设你正在编写 ...

  6. ajax同步,异步

    传输数据 同步:第一条传过去,对方接收到反馈以后,再传第二条; 异步:第一条传过去,不管对方有没有收到,继续传第二条. ajax(默认异步 async:true) 同步:执行完ajax内部代码,才执行 ...

  7. C/C++中产生随机数(rand,srand用法)

    计算机的随机数都是由伪随机数,即是由小M多项式序列生成的,其中产生每个小序列都有一个初始值,即随机种子.(注意: 小M多项式序列的周期是65535,即每次利用一个随机种子生成的随机数的周期是65535 ...

  8. UIview定义背景图片

    UIImage *image = [UIImage imageNamed:@"bgimagename"];    UIView *view = [[UIView alloc]ini ...

  9. SPOJ #440. The Turtle´s Shortest Path

    Coding a Dijkstra is not hard. %70 of my time spent on tackling TLE, as my last post. Dijkstra works ...

  10. android学习笔记21——消息提示Toast

    消息提示可细分为两种:大量消息提示——当程序有大量图片.信息需要展示时,采用对话框消息提示: 小量消息提示——当程序只有少量信息需要呈现给用户时,采用轻量级的对话框——Toast; Toast ==& ...