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,省去了调用默认构造函数的过程。也就是说,初始化的时候调用成员列表进行初始化,就不需要用自己默认的构造函数进行初始化了。这样如果有初始化列表,那么会调用拷贝构造函数进行初始化,从而省去了重载等号进行赋值的步骤,以及调用自己构造函数进行初始化的步骤。
所以一个好的原则是,能使用初始化列表的时候尽量使用初始化列表

初始化列表和构造函数内赋值的区别相关推荐

  1. C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别

    一般我们进行成员变量初始化用两种方法 第一种是通过在构造函数内赋值 class Point { public: Point(){ _x = 0; _y = 0;}; Point( int x, int ...

  2. 【C++】类的成员初始化表与构造函数内赋值操作

    我们常常在初始化类数据成员的时候,对使用初始化表和在构造函数中十分困惑,这二者有什么区别呢?我们应该如何选择呢? 先举个简单的例子,看下面的两段代码: 代码A: inline Account::Acc ...

  3. C++构造函数初始化列表与构造函数中的赋值的区别

    转载 C++构造函数初始化列表与构造函数中的赋值的区别 2016-12-10 15:16:51 xingpacer 阅读数 10391更多 分类专栏: C++相关 查看全文 http://www.ta ...

  4. 问题十六:使用初始化列表的构造函数和使用函数体的构造函数有什么区别?

    先看一段代码: class sphere: public hitable{ public: sphere() {} sphere(vec3 cen, float r) : center(cen), r ...

  5. 1.c++中初始化列表和构造函数初始化的区别是什么?2.类的成员变量的初始化顺序是按照声明顺序吗?

    初始化列表和构造函数初始化的区别是什么? 初始化和赋值对内置类型的成员没有太大的区别,在成员初始化列表和构造函数体内进行,在性能和结果上都是一样的.只有一些需要注意的事项 初始化列表一般情况如下: D ...

  6. c++ 初始化列表和构造函数初始化区别

    先上代码 #include <iostream>class MyContruct { public:MyContruct(){std::cout << "MyCont ...

  7. C++构造函数初始化列表与赋值

    C++中类的初始化操作一般有四个部分组成: 1.构造函数初始化列表 2.构造函数体内赋值 3.类外部初始化 4.类声明时直接赋值 对于内部数据类型(char,int,float...),构造函数初始化 ...

  8. C++ 类构造函数初始化列表介绍

    构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式. 构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个 ...

  9. C++类构造函数初始化列表

    构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式.例如: class CExample { public:     int a;     f ...

最新文章

  1. 英语四级计算机准考证查询,四级成绩查询_四级查分:什么?准考证不见了?!!!_沪江英语...
  2. 动态规划问题之一马当先
  3. JavaScript实现截留雨水问题的动态编程方法算法(附完整源码)
  4. 通用的异步处理类和进度通知类及其示例
  5. HALCON示例程序surface_scratch.hdev提取划痕
  6. 笔记本电池的正确使用方法
  7. eureka 注册中心高可用失败,没有互为副本
  8. 软件开发工作量/费用估算
  9. Excel批量随机生成姓名
  10. 帝国CMS文章内容超级伪静态 去除栏目id 以自定义英文名称和ID组成
  11. 电路图中电阻分类字母速记说明图文
  12. Soul是一个基于兴趣、场景、算法搭建的“第三空间”?
  13. 汉字字形码是计算机用来实现对汉字的输出,汉字编码字形码
  14. 无法激活服务,因为它不支持 ASP.NET 兼容性
  15. 【神奇的bug】main方法无法执行
  16. Weakly Supervised Instance Segmentation using Class Peak Response
  17. 挺带劲!这款开源数据库迁移工具超牛逼
  18. 查看oracle负载过大的原因,Oracle备份时系统负载过高导致ORA-3136错误和AIX系统的3D32B80D错误...
  19. 7月18百度测试实习生二面经历
  20. 机器学习相关资料推荐 http://blog.csdn.net/jiandanjinxin/article/details/51130271

热门文章

  1. 学python能做什么类型的工作-学点Python,让你的求职简历更有含金量!
  2. 学python有前途吗-现在学Python还有前途吗?能做什么?
  3. python和c++哪个好-Scratch和Python与C++选哪个合适
  4. android 4实例分析,OpenGL Shader实例分析(4)闪光效果
  5. arm thttpd php,thttpd嵌入式web开发笔记
  6. win102004优化_windows 10新版2004和1909该如何选择
  7. Vue左边与右边内容相关联
  8. 【python笔记】可迭代对象和迭代器
  9. 剑指 Offer II 006. 排序数组中两个数字之和
  10. 开源数字媒体资产管理系统:Razuna