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)转换构造函数 转换构造函数的定义:转换构造函数就是把普通的内置类型转换成类类型的构造函数,这种构造函数只有一个参数.只含有一个参数的构造函数,可以作为两种构造函数,一种是普通构造函数用于初始化对 ...
随机推荐
- Python - Django - ORM QuerySet 方法补充
models.py: from django.db import models class Employee2(models.Model): name = models.CharField(max_l ...
- DES 指定键的大小对于此算法无效
KEY (byte[]) 长度不为8. 一般KEY使用UTF8编码. byte[] byKey = Encoding.UTF8.GetBytes(key); 加密内容的编码,由两方协商. Sys ...
- 用MATLAB的Classficiation Learner工具箱对12个数据集进行各种分类与验证
准备材料 以所有的特征集作为variable进行像Bayes吖.SVM吖.决策树吖......分类.同时对数据进行预处理,选出相关度高的特征子集作为新的一组data进行分类(预处理的代码不必放出来). ...
- 第八章 跨语言服务治理方案 Service Mesh
8.1 Service Mesh 概述 新兴的下一代微服务架构,被称为下一代微服务,同时也是云原生技术栈的代表技术之一. 8.1.1 Service Mesh的由来 从2016年到2018年,serv ...
- Beta冲刺(1/4)
队名:秃头小队 组长博客 作业博客 组长徐俊杰 过去两天完成的任务:学习了很多东西 Github签入记录 接下来的计划:继续学习 还剩下哪些任务:后端部分 燃尽图 遇到的困难:自己太菜了 收获和疑问: ...
- 学习记录:《C++设计模式——李建忠主讲》7.“领域规则”模式
领域规则模式:在特定领域中,某些变化虽然频繁,但可以抽象为某种规则.这时候,结合特定的领域,将问题抽象为语法规则,从而给出该领域下的一般性解决方案. 典型模式:解释器模式(Interpreter). ...
- mogodb数据库简单的权限分配
mongdb数据库默认不需要权限认证,但为了安全起见,最好设置下需要权限认证,启动的时候设置auth=true即可. 推荐通过mongodb.conf配置文件的形式启动mongodb 进入mong ...
- ant 节点和属性
任务和javac命令是相似,它编译两种类型的java文件1)没有被编译的java文件2)曾经编译过,但是class文件版本和当前对应的java文件版本不匹配的java文件. 1)javac命令支持的参 ...
- 【Docker】:全面认识Docker和基本指令
Docker逐渐成为虚拟化技术的佼佼者,接下来会推出一系列的Docker相关技术文章,Docker技术也是架构师的必备技能. 什么是Docker Docker 是一个开源的应用容器引擎,基于Go语言, ...
- 剑指offer50:数组中重复的数字
1 题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长 ...