1 #include<iostream> 2 #include<string> 3 #include<set> 4 #include<time.h> 5 #include<cstring> 6 #include <vector> 7 #define LL long long 8 #define MAXN 100010 9 using namespace std; 10 int ask_int = 12; 11 double ask_double = 1.2; 12 13 /* 14 前置注意点: 15 我们定义类中的引用变量,一般是为了捕获类中的成员变量,而不是为了捕获外部变量,因为容易出现未可知的bug 16 这涉及到引用的底层机制,这里仅做引用的举例用(其实是知道的太晚了,代码写的差不多了),不要这样写代码。 17 https://zhuanlan.zhihu.com/p/262210907写的很好,给我很大启发 18 其实我们甚至很少把成员变量定义为引用 19 */ 20 class A { 21 public: 22 int &lim_num; 23 const int &lim_const_int; 24 const int const_int; 25 int num; 26 int &&right_num; 27 public: 28 //A() : lim_num(12),right_num(ask_int),const_int(18),lim_const_int(ask_int) {num = 1;cout<<lim_num<<"created"<<endl;} 29 /* 30 编译错误!注意第一项,没加const的引用不能够指向一个右值,而第二项必须用右值赋值 31 报错信息:cannot bind rvalue reference of type 'int&&' to lvalue of type 'int' 32 */ 33 //A() : lim_num(ask_double),right_num(ask_double),const_int(18),lim_const_int(20) {} 34 /*编译错误!注意第一项, 35 假设我们赋予的左值和我们的引用类型不同,那么会进行一次强制类型转换, 36 这次强制转换会产生一个临时常量 const int limi = (int) ask_double;(也许,总之系统将其视为一个右值,临时变量具有常性) 37 报错信息:cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int' 38 */ 39 A() : lim_num(ask_int),right_num(15),const_int(18),lim_const_int(20) {num = 1;cout<<"created"<<endl;} 40 41 A(int a,int b,int c,int d,int e) : lim_num(a),const_int(b),lim_const_int(c),right_num(165){num = d;cout<<"common created"<<endl;} 42 //A(const A &a) : lim_num(a.const_int),const_int(a.const_int),lim_const_int(a.lim_const_int),right_num(move(a.right_num)){num = a.num;cout<<"copy created"<<endl;} 43 /*出现bug,最好不要把引用往外指,这个地方可能是因为构造函数把变量副本压入栈中,然后引用绑定了这个栈的临时位置,栈中弹出的时候,就指向了未定义的位置*/ 44 A(const A &a) : lim_num(num),const_int(a.const_int),lim_const_int(a.lim_const_int),right_num(move(a.right_num)){num = a.num;cout<<"copy created"<<endl;} 45 /*注意最后一项,我们使用move把左值转换成右值*/ 46 A(A &&a) : lim_num(num),const_int(a.const_int),lim_const_int(a.lim_const_int),right_num(move(a.right_num)){num = a.num;cout<<"move created"<<endl;} 47 /*一定要采用括号赋值的方法,不能在大括号里对常量以及引用进行赋值*/ 48 ~A(){cout<<" deleted"<<endl;} 49 50 void printing() {cout<<" "<<lim_num<<" "<<const_int<<" "<<lim_const_int<<" "<<right_num<<" "<<num<<endl;} 51 }; 52 53 A rtti(const A &a) 54 { 55 return a; 56 } 57 58 int main() 59 { 60 int cxk = 12; 61 //无参测试 62 //A none_val(); //这种写法有误但是编译器不报错给你,它直接跳过,没有输出 63 A *none_val = new A(); //这样写就可以,调用无参构造函数 64 //none_val->func(); 65 66 //一般测试 67 A *common_val = new A(ask_int,14,161,18,244); 68 //A copy_val(*common_val); 69 common_val->printing(); 70 //拷贝测试 71 A copy_val = *common_val; 72 //引用外指出现位置bug,第一个引用参数对象变得混乱 73 //copy_val.printing(); 74 75 //移动测试 76 A move_val(12,15,16,187,258); 77 78 A las = rtti(move_val); 79 //las.printing(); 80 return 0; 81 } 82 83 /* 84 凡是有引用类型的成员变量或者常量类型的变量的类,不能有缺省构造函数。 85 默认构造函数没有对引用成员提供默认的初始化机制,也因此造成引用未初始化的编译错误。 86 并且必须使用初始化列表或直接赋值进行初始化const对象、引用对象。 87 */
