C++中类成员初始化方式详细说明
创始人
2024-03-24 13:24:21
0

在C++98中,支持了在类声明中使用等号“=”加初始值的方式,来初始化类中静态成员常量。这种声明方式我们也称之为“就地”声明。就地声明在代码编写时非常便利,不过C++98对类中就地声明的要求却非常高。如果静态成员不满足常量性,则不可以就地声明,而且即使常量的静态成员也只能是整型或者枚举型才能就地初始化。而非静态成员变量的初始化则必须在构造函数中进行。

1.初始化列表

class A
{
public:int a; // 初始化列表A(int a_):a(a_){}
};

2.构造函数初始化

class A
{
public:int a; // 初始化列表A(int a_, bool b) { a = a_; }
};

3.声明时初始化(也称就地初始化,c++11后支持)

class A
{
public:int a = 1; // 声明时初始化A() {}
};

在C++98中,支持了在类声明中使用等号“=”加初始值的方式,来初始化类中静态成员常量。这种声明方式我们也称之为“就地”声明。就地声明在代码编写时非常便利,不过C++98对类中就地声明的要求却非常高。如果静态成员不满足常量性,则不可以就地声明,而且即使常量的静态成员也只能是整型或者枚举型才能就地初始化。而非静态成员变量的初始化则必须在构造函数中进行。比如,如下代码在c++98中编译

class Init
{
public:Init(): a(0) []Init(int d): a(d) {}
private:int a;const static int b = 0;int c = 1;           // member, cannot pass buildstatic int d = 0;    // member, cannot pass buildstatic const double e = 1.3;      // not int or enum type, cannot pass buildstati const char* const f = "e";  // not int or enum type, cannot pass build
}

这非常不方便,所以在C++11中,标准允许非静态成员变量的初始化有多种形式。具体而言,除了初始化列表外,在C++11中,标准还允许使用等号= 或者 花括号{} 进行就地的非静态成员变量初始化。

struct init {int a = 1;double b {1.2};
};

因此假如三种初始化方式同时存在的话,那么最后保留的成员变量值肯定是构造函数中初始化的值。

#include 
using namespace std;
class A 
{
public:int a = 1;A(int a_) :a(2) { a = 3; }
};int main()
{A a;cout << "a.a=" << a.a << endl;return 0;
}// a.a=3

4.如何选择初始化方式

4.1 声明时初始化的使用场景

一个优点是直观,你在声明的时候顺便给一个初始值,别人在看你代码的时候,点一下调到声明也能看到你赋予的初始值,不用再去看构造函数那里给的什么值
第二个优点更有用了,比如你要定义多个构造函数,每个构造函数都用列表初始化的方法初始化,很麻烦,我们来看一下下面这个例子:

class Group {
public:Group() {}Group(int a): data(a) {}Group(Mem m): mem(m) {}Group(int a, Mem m, string n): data(a), mem(m), name(n) {}
private:int data = 1;Mem mem{0};string name{"Group"};
};

4.2 列表初始化的使用场景

前面说过了三个场景,这里赘述一下

  • const成员变量只能用成员初始化列表来完成初始化,而不能在构造函数内赋值
  • 初始化的数据成员是对象
  • 需要初始化引用成员数据
    但是,需要注意列表初始化的顺序,不过IDE会提示你的

4.3 构造函数初始化的使用场景

第一个就是拷贝和赋值构造函数里(不然怎么叫赋值构造函数呢)
第二个就是比较无聊的情况了,比如你想把几个成员函数都初始化成一个值,请看下面例子

class Group {
public:Group() {data1 = data2 = data3 = 0;}
private:int data1;int data2;int data3;
};

总而言之,优先就地初始化和列表初始化。

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...