C++——构造函数 constructor
What is constructor
- C++中,如果你想要创建一个object,有一个函数会自动被调用(不需要programmer显式调用 ),这个函数就是constructor;
- constructor的写法很独特,其function name必须和class name相同;
- constructor通过arguments上的差异进而形成ctor的overloading,当然和normal function一样,ctor也可以有default arguments;
- ctor没有返回值类型;
- ctor还有个特色功能(ctor独享),initialization list(初始化列表)。与在{ ... }内部赋值private data,initialization list速度会更快。简单讲,一个variable数值的设定有2个阶段,分别是initialization和assignment,initialization先于assignment阶段进行。initialization list就是发生在initialization阶段,{ ... }内部赋值private data属于assignment阶段。如果不使用initialization list表明你主动放弃initialization阶段工作,虽然最后你还是把数值放入到variable,但是时间晚了些,效率差了些;

默认实参,构造函数,普通函数都有这种性质。
ctor's overloading
参考:C++——overloading principle analysis
关于header file、static、inline、variable hides的一点感想
我们知道C不允许overloading,C++允许overloading。C++在编译器一侧时别到的函数名与我们看到的函数名是有很大差异的。normal function和ctor的overloading方式差不多。下图事normal function的重载。

注意:黄色部分①②两个ctor则不可以同时存在,①对于的ctor所有形参都有默认参数,这时候就相当于default ctor,和②是一样的效果。编译器在这种情况下无法做出选择。虽然这也是overloading,但是这种overloading让compiler困惑
常量成员函数

在函数后头加const,表示函数不会改变调用者的内容,或 形参在函数内部不会改变。
如果忘记加const,右下角的例子,c1是个常量,而real和imag却有可能改变c1,产生矛盾,编译器报错。
singleton——把构造函数放在private区
design patrern中 的一种模式

构造函数的作用
①构造对象:在用类定义一个对象时会自动调用构造函数
②初始化对象:类的数据成员往往放在构造函数里面初始化
③类型转换:看讲解
无论C 、C++都是强类型语言,不同类型变量之间不能随便赋值。很多时候我们认为理所当然的赋值都是借助临时变量来实现的。看代码
#include<iostream>
class Test {
public:
Test(int a=)
{
std::cout << "Create Test Object:" << this<<std::endl;
this->a = a;
}
~Test()
{
std::cout << "Free Test Object:" << this << std::endl;
}
private:
int a;
}; int main(int argc, char **argv)
{
Test t1;
t1 = ;
getchar();
return ;
}
调试结果

这里调用了2此构造函数,2次析构函数(析构顺序是栈操作顺序)。输出结果解析
第1行输出:执行第19行,调用构造函数
第2行输出:执行第20行,调用构造函数。这里创建了一个临时Test类型对象(C++为了凸显逼格把类类型的变量称为对象),100就是传入构造函数的参数。
第3行输出:第2行构造完临时对象后,赋值给了对象t1。赋值以后临时对象的生命期就结束了,这里调用析构函数,终结这个临时对象
第4行输出:第22行return 0返回后调用析构函数,终结对象t1
画图解释这一过程

这里面最关键的一个环节就是int类型到Test临时对象转换,int类型要找到一个途径来转换成Test类型。这个途径是什么呢? 构造函数
而我们代码里面恰恰有这么个构造函数,他的参数就是一个整形。如果我们干掉这个构造函数,换一个不带参数的构造函数(或者干脆不写构造函数,使用默认的),则不能将100赋值给t1
代码如下
#include<iostream>
class Test {
public:
Test()
{
std::cout << "Create Test Object:" << this << std::endl;
this->a = a;
}
~Test()
{
std::cout << "Free Test Object:" << this << std::endl;
}
private:
int a;
}; int main(int argc, char **argv)
{
Test t1;
t1 = ;
getchar();
return ;
}
#include<iostream>
class Test {
public:
~Test()
{
std::cout << "Free Test Object:" << this << std::endl;
}
private:
int a;
}; int main(int argc, char **argv)
{
Test t1;
t1 = ;
getchar();
return ;
}
这种情况直接编译不过。错误 C2679 二进制“ = ”: 没有找到接受“int”类型的右操作数的运算符(或没有可接受的转换)。在类型转换的时候,编译器试图寻找能实现转换的构造函数,能找到就执行构造函数生成一个临时对象好用于赋值。找不到就报错。
额外补充:对于隐式类型转换,生成的临时对象具有const性质。参考 C++——引用
explicit关键字
有的时候我们会发现构造函数前面加了个关键字explicit,代码如下
#include<iostream>
class Test {
public:
explicit Test(int a = )
{
std::cout << "Create Test Object:" << this << std::endl;
this->a = a;
}
~Test()
{
std::cout << "Free Test Object:" << this << std::endl;
}
private:
int a;
}; int main(int argc, char **argv)
{
Test t1;
t1 = (Test);
getchar();
return ;
}
在进行赋值 或 类型转换的时候,如果要借助构造函数是不允许隐式转换的。所以第20行必须强制转换(显式转换)。
C++——构造函数 constructor的更多相关文章
- javascript工厂函数(factory function)vs构造函数(constructor function)
如果你从其他语言转到javascript语言的开发,你会发现有很多让你晕掉的术语,其中工厂函数(factory function)和构造函数(constructor function)就是其中的一个. ...
- 类(class)、构造函数(constructor)、原型(prototype)
类 Class 类的概念应该是面向对象语言的一个特色,但是JavaScript并不像Java,C++等高级语言那样拥有正式的类,而是多数通过构造器以及原型方式来仿造实现.在讨论构造器和原型方法前,我可 ...
- JavaScript中的类(class)、构造函数(constructor)、原型(prototype)
类 Class 类的概念应该是面向对象语言的一个特色,但是JavaScript并不像Java,C++等高级语言那样拥有正式的类,而是多数通过构造器以及原型方式来仿造实现.在讨论构造器和原型方法前,我可 ...
- 构造函数constructor 与析构函数destructor(四)
拷贝构造函数:拷贝构造函数就是在用一个类对象来创建另外一个类对象时被调用的构造函数,如果我们没有显示的提供拷贝构造函数,编译器会隐式的提供一个默认拷贝构造函数. 拷贝构造函数的定义是X(const X ...
- 构造函数constructor 与析构函数destructor(一)
构造函数定义:构造函数c++中在创建对象时自动调用,用来初始化对象的特殊函数. (1)构造函数的名字必须与类的名字相同,不能有返回值,哪怕是void 也不行. (2)通常情况下构造函数应声明为公有函数 ...
- C++ 类 构造函数 constructor
构造函数 当定义了一个整型变量: int a; 这会申请了一块内存空间来存储a,但是这块内存中原本有数据的,可能是任何值,这不是你所希望的,若你就希望a表示1,所以要把a的值赋值为1. ; 例: #i ...
- 构造函数constructor 与析构函数destructor(五)
我们知道当调用默认拷贝构造函数时,一个对象对另一个对象初始化时,这时的赋值时逐成员赋值.这就是浅拷贝,当成员变量有指针时,浅拷贝就会在析构函数那里出现问题.例如下面的例子: //test.h #ifn ...
- 构造函数constructor 与析构函数destructor(三)
(1)构造函数初始化列表: 1 class Test{ 2 int i; 3 public: 4 Test(int vi):i(vi){}//这里的从冒号开始,到右大括号结束,这一段是构造函数初始化列 ...
- 构造函数constructor 与析构函数destructor(二)
(1)转换构造函数 转换构造函数的定义:转换构造函数就是把普通的内置类型转换成类类型的构造函数,这种构造函数只有一个参数.只含有一个参数的构造函数,可以作为两种构造函数,一种是普通构造函数用于初始化对 ...
随机推荐
- expect 实现自动交互脚本
1. 说明 在编写脚本时,可能会遇到需要在另一台主机上执行一个命令,或者在本机拷贝另一台主机内的一个文件.如果两台主机之间没有做互信,就会牵扯到用户输入密码的交互过程,这对编写自动脚本来说, 就行不通 ...
- 常见问题:MySQL/索引
普通索引 最常用,没有任何限制. 唯一索引 必须唯一,但允许空值,如果是组合索引,列值的组合必须唯一. 组合索引 由于MySQL查询时,只能使用一个索引,因此建立组合索引在组合查询的场景下更加有效.组 ...
- sql 查找最晚入职员工
题目描述 查找最晚入职员工的所有信息CREATE TABLE `employees` (`emp_no` int(11) NOT NULL,`birth_date` date NOT NULL,`fi ...
- qbittorrent搜索在线插件
https://raw.githubusercontent.com/khensolomon/leyts/master/yts.py https://raw.githubusercontent.com/ ...
- TCP/UDP网络编程调试助手下载
下载地址:可能需要谷歌:软件干净,挺好用的,如果有更好的,欢迎留言! https://www.waveshare.com/wiki/File:TCP-UDP-Debug.7z
- Linux下指定so共享库的加载路径
转载地址:https://blog.csdn.net/zorelemn/article/details/52596293,做了部分修改 一.库文件的搜索路径: 1.在配置文件/etc/ld.so.co ...
- LeetCode 617. 合并二叉树(Merge Two Binary Trees)
617. 合并二叉树 617. Merge Two Binary Trees 题目描述 给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠. 你需要将他们合并为一个新 ...
- 033 Android App启动的闪屏效果+新手向导(多个图片滑动效果)+ViewPager使用
1.目标效果 App启动时,出现闪屏效果(利用动画实现). App新手使用时,会出现新手向导效果. 2.XML页面布局 (1)闪屏页面 <?xml version="1.0" ...
- 021 Android 查询已经导入到工程中的数据库+抖动效果
1.将数据库(.db)文件放入工程中 在project状态下,新建assets文件夹,并将数据库文件放入assets目录下. 注意:assets目录.java目录.res目录是同级的 new---&g ...
- Python3之字符串格式化format函数详解(上)
概述 在Python3中,字符串格式化操作通过format()方法或者f’string’实现.而相比于老版的字符串格式化方式,format()方法拥有更多的功能,操作起来更加方便,可读性也更强.该函数 ...