C++11_列表初始化及类内初始化

1 列表初始化语法 initializer_list<>

C++11中,集合(列表)的初始化已经成为C++语言的一个基本功能,这种初始化的方法被称为“初始化列表”(initializer list),例如:

#include <vector>
#include <map>

using namespace std;

int a[] = {1, 3, 5};
int b[]{2, 4, 6};
vector<int> c{1, 3, 5};
map<int, float> d =
        {{1, 1.0f},
         {2, 2.0f},
         {5, 3.2f}};

这样一来,自动变量和全局变量的初始化在C++11中被丰富了,程序员可以使用以下几种形式完成初始化的工作

  • 等号“=”加上赋值表达式(assignment-expression),比如 int a = 3 + 4;
  • 等号“=”加上花括号式的初始化列表,比如 int a = {3 + 4};
  • 圆括号式的表达式列表(expression-list),比如 int a (3 + 4);
  • 花括号式的初始化列表,比如 int a {3 + 4};

后面2种形式也可以用于获取堆内存new操作符中,比如:

int* i = new int(1);
double* d = new double{1.2f};

自定义的类如果要使用初始化列表初始化,需要#include <initializer_list>头文件,并且声明一个以initializer_list模板类为参数的构造函数:

#include <vector>
#include <map>

using namespace std;

enum Gender {
    boy, girl
};

class People {
public:
    People(initializer_list<pair<string, Gender>> l) { // initializer_list的构造函数
        auto i = l.begin();
        for (; i != l.end(); ++i)
            data.push_back(*i);
    }

private:
    vector<pair<string, Gender>> data;
};

People ship2012 = {{"Garfield", boy}, {"HelloKitty", girl}};

同样的,函数的参数列表也可以使用初始化列表:

#include <initializer_list>

using namespace std;

void Fun(initializer_list<int> iv) { }

int main() {
    Fun({1, 2});
    Fun({}); // 空列表
}

可有接收任意个数的初始化值

void print(std::initializer_list<int> vals) {
    for (auto p = vals.begin(); p != vals.end(); ++p) {  // a list of values
		std::cout << *p << "\n";
    }
}

print({1, 3, 5, 7, 11, 13, 17});  // pass a list of values to print()

列表初始化语法对于STL容器和自定义类作用很大(尤其是一些测试代码),但对于数组等类型就没必要强制使用了。总的来说,这是一个能在部分场景下大大提高效率的值得推广的特性。

相关链接:https://zh.cppreference.com/w/cpp/language/list_initialization

2 类内初始化

2.1 内置类型

int i{0};
int i = {0};
int i = 0;
int i(0);

float f{3.6};
float f = {3.6};
float f = 3.6;
float f(3.6);

char chArr[] = {`c`, `h`, `a`, `r`};
char chArr[]{`c`, `h`, `a`, `r`};

char* c = new char{`g`};
char* c = new char(`g`);

2.2 数组

char chArr[]{`c`, `h`, `a`, `r`};
char chArr[] = {`c`, `h`, `a`, `r`};

2.3 STL标准模板库

std::vector<int> v = {1, 2, 3};
std::vector<int> v{1, 2, 3};
std::pair<int, std::string> p = {1, "one"};

2.4 函数

2.4.1 函数参数

大括号表达式做实参传入时,会构造一个initializer_list<int>对象。

#include <initializer_list>
#include <iostream>

void DisplayInt(const std::initializer_list<int>& ivec)
{
	for (auto i : ivec) {
		std::cout << i << std::endl;
	}
}

int main()
{
	DisplayInt({1, 2, 3, 4, 5, 6, 7, 8, 9});
	return 0;
}
2.4.2 函数的返回值

2. 5 自定义的类

在C++03中对类的成员变量初始化有两种方式:

  • 构造函数初始化列表
  • 构造函数内部赋值

一般前者效率会更高。

在C++11中为了避免当内部成员变量较多时,初始化列表显得冗长,开始支持在成员变量中声明时,直接对其进行赋值操作或者初始化列表。

class Test {
public:
	Test(){}
private:
	int value = 0;
	std::string name {"Test"};
};

其执行的顺序为:

  1. 直接赋值操作
  2. 初始化列表
  3. 构造函数内部初始化

其三者可以同时使用,不冲突。

注意:C++11 中不支持在类内部用小括号进行直接赋值操作。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值