初始化列表和构造函数内赋值的区别
1. 类的静态成员变量不能用参数初始化表初始化
(1) 如果声明了类而未定义对象,则类的一般数据成员是不占内存空间的,只有在定义对象时,在运行的时候才为对象的数据成员分配空间。但是静态数据成员不属于某一个对象,在为对象所分配的空间中不包括静态数据成员所占的空间。静态数据成员是在所有对象之外单独开辟空间,也就是在静态变量区。只要在类中指定了静态数据成员,即使不定义对象,也为静态数据成员分配空间,它可以被引用。
(2) 一般的类的成员随对象的建立而分配空间,随对象的撤销而释放。静态数据成员是在程序编译时被分配空间的,至程序结束时才释放空间。
(3) 静态数据成员可以初始化,但只能在类体外进行初始化。
也就是说,静态数据成员可以初始化,但只能在类体外初始化,并且不能用参数初始化表对其初始化。
如: class Box
{
public:
int volume();
private:
static int height;
int width;
int length
}
int Box::height = 10; //正确
Box(inth, int w, int len):height(h){} //错误
静态成员与对象无关,属于整个类,构造函数是构造某个具体的对象。创建一个对象的时候会用到初始化表,但是静态成员在对象创建之前(在编译的时候)就已经存在了,所以不需要再初始化表中初始化。
2. 常数据成员只能通过构造函数初始化表对其进行初始化
常数据成员只能通过构造函数初始化表对其进行初始化,任何其它函数都不能对常数据成员赋值。如类体中定义了常数据成员hour:
const int hour;//定义hour为常数据成员;
Time::Time(inth)
{hour= h;} // 非法,普通赋值函数不能对之赋值
如果在类体外定义构造函数,应写成如下形式:
Time::Time(inth):hour(h){} //通过参数初始化表对常数据成员hour初始化
为什么只有初始化列表而不是普通函数能对常变量进行初始化呢?一般变量赋值有两种:一是使用初始化列表,二是在构造函数体内进行赋值操作。由于常量只能初始化不能赋值,所以常量成员必须使用初始化列表。
3、主要是性能问题,对于内置类型,如int, float等,使用初始化类表和在构造函数体内初始化差别不是很大,但是对于类类型来说,最好使用初始化列表,为什么呢?使用初始化列表少了一次调用默认构造函数的过程,这对于数据密集型的类来说,是非常高效的。这部分我参考了:https://blog.csdn.net/baidu_35679960/article/details/78929018
#include <iostream>
using namespace std;
class Test1
{
public:
Test1() {cout << "Construct Test1" << endl ;} // 无参构造函数
Test1(const Test1& t1) // 拷贝构造函数
{
cout << "Copy constructor for Test1" << endl ;this->a = t1.a ;
}
Test1& operator = (const Test1& t1) // 重载赋值运算符(也称为重载赋值函数)
{
cout << "assignment for Test1" << endl ;
this->a = t1.a ;
return *this;
}
private:
int a ;
};
class Test2
{
public:
Test1 test1; //此处第二次调用Test 1的construct;
//std::cout<<"进入Test2 的构造函数"<<std::endl; //类中只能包含成员变量和成员函数!
Test2(Test1 &t1){test1 = t1 ;} //此处的“=”调用重载的“=”操作符;
};
int main(){
Test1 t1; //此处第一次调用Test1的construct;
cout<<"end of fist construct t1"<<endl;
Test2 t2(t1);
}
输出为:
Construct Test1
end of fist construct t1
Construct Test1
assignment for Test1
解释一下:
第一行输出对应调用代码中第一行,构造一个Test1对象
第三行输出对应Test2构造函数中的代码,用默认的构造函数初始化对象test1 // 这就是所谓的初始化阶段
第四行输出对应Test2的赋值运算符,对test1执行赋值操作 // 这就是所谓的计算阶段
如果使用初始化列表来实现Test2的构造函数;
class Test2
{
public:
Test1 test1 ;
Test2(Test1 &t1):test1(t1){}
};
输出为:
Construct Test1
end of fist construct t1
Copy constructor for Test1
第一行输出对应 调用代码的第一行
第三行输出对应Test2的初始化列表,直接调用拷贝构造函数初始化test1,省去了调用默认构造函数的过程。也就是说,初始化的时候调用成员列表进行初始化,就不需要用自己默认的构造函数进行初始化了。这样如果有初始化列表,那么会调用拷贝构造函数进行初始化,从而省去了重载等号进行赋值的步骤,以及调用自己构造函数进行初始化的步骤。
所以一个好的原则是,能使用初始化列表的时候尽量使用初始化列表
初始化列表和构造函数内赋值的区别相关推荐
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别
一般我们进行成员变量初始化用两种方法 第一种是通过在构造函数内赋值 class Point { public: Point(){ _x = 0; _y = 0;}; Point( int x, int ...
- 【C++】类的成员初始化表与构造函数内赋值操作
我们常常在初始化类数据成员的时候,对使用初始化表和在构造函数中十分困惑,这二者有什么区别呢?我们应该如何选择呢? 先举个简单的例子,看下面的两段代码: 代码A: inline Account::Acc ...
- C++构造函数初始化列表与构造函数中的赋值的区别
转载 C++构造函数初始化列表与构造函数中的赋值的区别 2016-12-10 15:16:51 xingpacer 阅读数 10391更多 分类专栏: C++相关 查看全文 http://www.ta ...
- 问题十六:使用初始化列表的构造函数和使用函数体的构造函数有什么区别?
先看一段代码: class sphere: public hitable{ public: sphere() {} sphere(vec3 cen, float r) : center(cen), r ...
- 1.c++中初始化列表和构造函数初始化的区别是什么?2.类的成员变量的初始化顺序是按照声明顺序吗?
初始化列表和构造函数初始化的区别是什么? 初始化和赋值对内置类型的成员没有太大的区别,在成员初始化列表和构造函数体内进行,在性能和结果上都是一样的.只有一些需要注意的事项 初始化列表一般情况如下: D ...
- c++ 初始化列表和构造函数初始化区别
先上代码 #include <iostream>class MyContruct { public:MyContruct(){std::cout << "MyCont ...
- C++构造函数初始化列表与赋值
C++中类的初始化操作一般有四个部分组成: 1.构造函数初始化列表 2.构造函数体内赋值 3.类外部初始化 4.类声明时直接赋值 对于内部数据类型(char,int,float...),构造函数初始化 ...
- C++ 类构造函数初始化列表介绍
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式. 构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个 ...
- C++类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式.例如: class CExample { public: int a; f ...
最新文章
- 英语四级计算机准考证查询,四级成绩查询_四级查分:什么?准考证不见了?!!!_沪江英语...
- 动态规划问题之一马当先
- JavaScript实现截留雨水问题的动态编程方法算法(附完整源码)
- 通用的异步处理类和进度通知类及其示例
- HALCON示例程序surface_scratch.hdev提取划痕
- 笔记本电池的正确使用方法
- eureka 注册中心高可用失败,没有互为副本
- 软件开发工作量/费用估算
- Excel批量随机生成姓名
- 帝国CMS文章内容超级伪静态 去除栏目id 以自定义英文名称和ID组成
- 电路图中电阻分类字母速记说明图文
- Soul是一个基于兴趣、场景、算法搭建的“第三空间”?
- 汉字字形码是计算机用来实现对汉字的输出,汉字编码字形码
- 无法激活服务,因为它不支持 ASP.NET 兼容性
- 【神奇的bug】main方法无法执行
- Weakly Supervised Instance Segmentation using Class Peak Response
- 挺带劲!这款开源数据库迁移工具超牛逼
- 查看oracle负载过大的原因,Oracle备份时系统负载过高导致ORA-3136错误和AIX系统的3D32B80D错误...
- 7月18百度测试实习生二面经历
- 机器学习相关资料推荐 http://blog.csdn.net/jiandanjinxin/article/details/51130271
热门文章
- 学python能做什么类型的工作-学点Python,让你的求职简历更有含金量!
- 学python有前途吗-现在学Python还有前途吗?能做什么?
- python和c++哪个好-Scratch和Python与C++选哪个合适
- android 4实例分析,OpenGL Shader实例分析(4)闪光效果
- arm thttpd php,thttpd嵌入式web开发笔记
- win102004优化_windows 10新版2004和1909该如何选择
- Vue左边与右边内容相关联
- 【python笔记】可迭代对象和迭代器
- 剑指 Offer II 006. 排序数组中两个数字之和
- 开源数字媒体资产管理系统:Razuna