C++:常见类型的初始化
1. 背景
常见类型 | 包含 |
---|---|
内置类型 | 整型(布尔型,字符型,整型)、浮点型 |
复合类型 | 引用、指针、数组 |
标准库类型 | string、vector |
2. 初始化
2.1 整型和浮点型初始化
整型和浮点型初始化时会自动进行类型转换。
#include <iostream>
using namespace std;
int main()
{
int i1 = 1;
const int i2 = 1;
double d1 = 3.14;
const double d2 = 3.14;
int x1 = i1; // int <- int
int x2 = i2; // int <- const int
int x3 = d1; // int <- double
int x4 = d2; // int <- double
const int x5 = i1; // const int <- int
const int x6 = i2; // const int <- const int
const int x7 = d1; // const int <- const double
const int x8 = d2; // const int <- const double
return 0;
}
2.2 引用类型初始化
引用的类型必须与其所绑定对象的类型一致。只要表达式结果可以转换成引用的类型,对常量的引用就允许以它作为初始值。若类间存在继承关系,则对基类的引用可以绑定派生类对象。
#include <iostream>
using namespace std;
class A
{
public:
int a;
};
class B : public A
{
public:
int b;
};
main()
{
int i;
const int ci = 1;
double d = 3.14;
const double cd = 3.14;
//引用的类型必须与其所绑定对象的类型一致
int &x1 = i; //正确:x1绑定int,i是int
int &x2 = ci; //错误:类型不匹配,x2绑定int,ci是const int
int &x3 = d; //错误:类型不匹配,x3绑定int,d是double
int &x4 = cd; //错误:类型不匹配,x4绑定int,cd是const double
//引用特例:对常量的引用
const int &y1 = i;
const int &y2 = ci;
const int &y3 = d; //正确:d是double,可以转换成const int。
const int &y4 = cd; //正确,等价于const int temp = cd;const int &y4 = temp;
const int &y5 = 1; //正确,等价于const int temp = 1;const int &y5 = temp;
const int &y6 = 3.14; //正确,等价于const int temp = 3.14;const int &y6 = temp;
A a;
B b;
A &a1 = b; //引用特例:对基类的引用
B &b1 = a; //错误:类型不匹配,b1引用B,a是A
return 0;
}
2.3 指针类型初始化
指针的类型必须与其所指对象的类型一致。指向常量的指针可以指向一个相应的非常量对象。若类间存在继承关系,指向基类的指针可以指向派生类对象。
#include <iostream>
using namespace std;
class A
{
public:
int a;
};
class B : public A
{
public:
int b;
};
main()
{
int i = 1;
const int ci = 1;
double d = 3.14;
const double cd = 3.14;
//指针的类型必须与其所指对象的类型一致
int *x1 = &i; //正确:x1指向int,i1是int
int *x2 = &ci; //错误:类型不匹配,x2指向int,ci是const int
int *x3 = &d; //错误:类型不匹配,x3指向int,d是double
int *x4 = &cd; //错误:类型不匹配,x4指向int,cd是const double
//指向常量的指针可以指向一个相应的非常量对象
const int *y1 = &i; //正确:y1指向const int,i1是int(指针特例)
const int *y2 = &ci; //正确:y2指向const int,ci是const int
const int *y3 = &d; //错误:类型不匹配,y3指向const int,d是double
const int *y4 = &cd; //错误:类型不匹配,y4指向const int,cd是const double
//存在继承关系的类,指向基类的指针可以指向派生类对象
A a;
B b;
A *a1 = &b; //正确:(引用特例)
B *b1 = &a; //错误:类型不匹配,b1指向B,a是A。
return 0;
}
2.4 绑定指针的引用初始化
先看引用是否是对常量的引用,按上述引用的规则执行。再看绑定的指针是否指向常量,按上述指针的规则执行。
#include <iostream>
using namespace std;
class A
{
public:
int a;
};
class B : public A
{
public:
int b;
};
main()
{
int i, *pi;
const int ci = 1, *pci;
double d = 3.14, *pd;
const double cd = 3.14, *pcd;
//指针是变量,故引用是对变量的引用,类型需严格匹配。
//-----------------------------------------------------------------------------------------------
int *&x1 = &i; //错误:引用只能绑定对象(左值),不能绑定字面值或表达式计算结果(右值)
int *&x1 = pi; //正确: x2绑定int*,pci是int*
int *&x2 = pci; //错误:类型不匹配,x2绑定int*,pci是const int*
int *&x3 = pd; //错误:类型不匹配,x3绑定int*,pd是double*
int *&x4 = pcd; //错误:类型不匹配,x4绑定int*,pcd是const double*
//指针是变量,故引用是对变量的引用,类型需严格匹配。
//-----------------------------------------------------------------------------------------------
const int *&y1 = pi; //错误:类型不匹配,y1绑定const int*,pi是int*
const int *&y2 = pci; //正确: y2绑定const int*,pci是const int*
const int *&y3 = pd; //错误:类型不匹配,y3绑定const int*,pd是double*
const int *&y4 = pcd; //错误:类型不匹配,y4绑定const int*,pcd是const double*
//指针本身是常量,故引用是对常量的引用。指针指向变量,类型需严格匹配。
//-----------------------------------------------------------------------------------------------
int *const &m1 = pi; //正确: 指针指向int,pi指向int
int *const &m2 = pci; //错误:类型不匹配,指针指向int,pci指向const int
int *const &m3 = pd; //错误:类型不匹配,指针指向int,pd指向double
int *const &m4 = pcd; //错误:类型不匹配,指针指向int,pcd指向const double
//指针本身是常量,故引用是对常量的引用。指针指向常量,允许指向常量的指针指向一个对应的非常量。
//-----------------------------------------------------------------------------------------------
const int *const &n1 = pi; //正确: 指针指向const int,pi指向int(指向常量的指针可以指向一个对应的非常量)
const int *const &n2 = pci; //正确: 指针指向const int,pci指向const int
const int *const &n3 = pd; //错误:类型不匹配,指针指向const int,pd指向double
const int *const &n4 = pcd; //错误:类型不匹配,指针指向const int,pcd指向const double
return 0;
}
2.5 数组初始化。
数组一般用花括号初始化,数组间不能初始化、赋值和拷贝。
#include <iostream>
using namespace std;
main()
{
int i = 1;
const int ci = 1;
int x1[3];
int x2[3] = {1, 2, 3};
int x3[3] = {1, 3.14, ci};
const int x4[3] = {1, 3.14, ci};
//不能用一个数组初始化另一数组
// int i4 = i1;
return 0;
}
2.6 string初始化。
#include <iostream>
#include <string>;
using namespace std;
int main()
{
string s1;
string s2(s1);
string s3("abc");
string s4(3, 'a');//s4=aaa
string s5{"abc"};
string s6 = s1;
string s7 = "abc";
string s8 = 'a' + s1;//s8=a
// string s9 = 'a' + 'b' + s1;//错误:加号两边至少有一边是string类型
return 0;
}
2.7 vector初始化
#include <iostream>
#include <vector>;
using namespace std;
int main()
{
vector<string> vi1;
vector<string> vi2(vi1);
vector<string> vi3(3); //vi3包含3个元素
vector<string> vi4(3, "a"); //vi4包含3个元素,每个元素的初值为a
vector<string> vi5{"a", "b"}; //vi5包含2个元素,初值分别是a和b
vector<string> vi6 = vi1;
vector<string> vi7 = {"abc"};
return 0;
}