hello~ 很高兴见到大家! 这次带来的是C++中关于C++11这部分的一些知识点,如果对你有所帮助的话,可否留下你宝贵的三连呢? 个 人 主 页: 默|笙


struct Point
{
int _x;
int _y;
};
class Date
{
public:
Date(int year = 1, int month = 1, int day = 1)
:_year(year)
, _month(month)
, _day(day)
{
cout << "Date(int year, int month, int day)" << endl;
}
Date(const Date& d)
:_year(d._year)
, _month(d._month)
, _day(d._day)
{
cout << "Date(const Date& d)" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
//c++98
int a[] = { 1, 2, 3, 4, 5 };
int a2[5] = { 1, 2, 3, 4, 5 };//数组
Point p = { 1, 2 };//结构体
//c++11
int x1 = { 2 };
int x2{ 2 };//可以不带等号
Date d1 = { 2025, 1, 1 };
const Date& d2 = { 2025, 1, 2 };
//引用的是{2025,1,2}构造的临时对象
Date d3 = { 2025 };
Date d4 = 2025;
//C++98支持单参数隐式转换,可以不用{},这个是不能省略=号的
vector<Date> v;
v.push_back(d1);
v.push_back({ 2025, 1, 1 });//可以直接用{}初始化后传参
return 0;
}

auto il = { 1,2,3,4,5,6,7,8,8 };
cout << sizeof(il) << endl;
cout << typeid(il).name() << endl;
map<int, int> m = { {1, 1}, {2, 2} };
//pair类型:{}列表调用其他的构造函数初始化pair类型,再通过initializer_list(外面的这个{})整个构造。C++11增加了右值引用语法特性,在这之前学到过的引用叫做左值引用。无论是左值引用还是右值引用,它们的作用都是给对象起别名。
int* p = new int(0);//指针变量p
cout << &p << endl;
int b = 1;//普通变量b
cout << &b << endl;
const int c = b;//const变量c
cout << &c << endl;
*p = 10;//指针解引用
cout << &*p << endl;
string s("123");//string类对象s
cout << &s << endl;
s[0] = 'x';//类成员访问(另类指针解引用)
cout << (void*) & s[0] << endl;
//&s[0]是char*类型,编译器会对其特殊处理,将其视为c风格字符串进行打印
//所以要强转成其他类型如void*
10;//字面量常量
x + y;//运算产生临时变量
fmin(x, y);//函数返回值
string("111");//匿名对象
double x = 1.1, y = 4.4;
int&& rr1 = 10;//右值引用右值
int& r1 = 10;//左值引用不能够直接引用右值
const int& cr1 = 10;//const左值引用能够引用右值
double&& rr0 = x;//右值不能引用左值
double&& rr00 = move(x);//可以将x用move处理一下,就能被右值引用取别名了
double&& rr000 = (double&&)x;//其实move和这里的强转操作目前可以认为是等价的
double&& rr2 = x + y;
double& r2= x + y;
const double& cr2 = x + y;
double&& rr3 = fmin(x, y);
double& r3 = fmin(x, y);
const double& cr3 = fmin(x, y);
string&& rr4 = string("111");
string& r4 = string("111");
const string& cr4 = string("111");
string s1("111");
const string& s2 = s1 + s1;
s2 += "2";
string&& s3 = s1 + s1;
s3 += "2";
void func(int& x)
{
std::cout << "左值引用重载 f(" << x << ")\n";
}
void func(const int& x)
{
std::cout << "const的左值引用重载 f(" << x << ")\n";
}
void func(int&& x)
{
std::cout << "右值引用重载 f(" << x << ")\n";
}
int main()
{
int x = 1;
const int y = 2;
func(x);
func(y);
func(10);
func(move(x));
return 0;
}

mosheng::string s1("xxxxxxx");
mosheng::string s2 = s1;
mosheng::string s3 = move(s1);


// 移动构造
string(string&& s)
{
cout << "string(string&& s) -- 移动构造" << endl;
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}



//由于引用折叠,左值引用无论是跟它的左值引用还是右值引用折叠,结果都是左值引用
template<class T>
void f1(T& x)
{}
//右值引用的右值用折叠是右值引用,跟它的左值引用折叠是左值引用,可以折叠出两种结果,也叫做万能引用
template<class T>
void f2(T&& x)
{}
int main()
{
int n = 0;
//传递左值,T为int类型,实例化为void f1(int& x)
f1<int>(n);
//传递的右值,int& 无法匹配右值,编译报错
//f1<int>(0);
//传递左值,T为int&类型,折叠之后还是左值引用,实例化为void f1(int& x)
f1<int&>(n);
//传递右值,int& 无法匹配右值,编译报错
//f1<int&>(0);
//传递左值,T为int&&类型,折叠之后还是左值引用,实例化为void f1(int& x)
f1<int&&>(n);
//传递右值,int& 无法匹配右值,编译报错
//f1<int&&>(0);
//T为const int&类型,折叠之后为const int&,实例化为void f1(const int& x),左值和右值都可以匹配上
f1<const int&>(n);
f1<const int&>(0);
//T为const int&&类型,折叠之后为const int&,实例化为void f1(const int& x),左值和右值都可以匹配上
f1<const int&&>(n);
f1<const int&&>(0);
//传递左值,T为int类型,实例化为void f2(int&& x),int&& 无法匹配左值,编译报错
//f2<int>(n);
f2<int>(0);
//T为int&类型,左值引用的右值引用折叠后为左值引用,实例化为void f2(int& x)。左值能匹配,右值报错
f2<int&>(n);
//f2<int&>(0);
//T为int&&类型,右值引用的右值引用折叠后为左值引用,实例化为void f2(int&& x)。
//f2<int&&>(n);
f2<int&&>(0);
return 0;
}



今天的分享就到此结束啦,如果对读者朋友们有所帮助的话,可否留下宝贵的三连呢~~ 让我们共同努力, 一起走下去!