建议直接复制代码运行测试
//
// C++11 之后参数传递的六种方式
//
#include <iostream>
using namespace std;
struct CpySpy
{
unsigned count = 1;
CpySpy() {}
CpySpy(const CpySpy& obj) :
count(obj.count + 1)
{
cout << "copy count: " << count << endl;
}
};
#define BYREF
#ifdef BYVAL // 按值传递会有拷贝过程,可以同时匹配左值、右值、常左值、常右值
#ifndef CONST // 按值传递和按引用传递都可以匹配所有传参,因而互不兼容
// 1.按值传递
void foo(CpySpy cs) { cout << "foo(CpySpy)" << endl; }
#else
// 2.按常值传递,用处很少,这种情况下多用常引用
void foo(const CpySpy cs) { cout << "foo(const CpySpy)" << endl; }
#endif
#endif
#ifdef BYREF // 按引用传递没有拷贝过程,左值右值分开匹配(引用和值互不兼容)
// 3.按引用传递 优先级 左值 右值 常左值 常右值
void foo(CpySpy& cs) { cout << "&" << endl; } // 1 X X X
// 4.按常引用传递
void foo(const CpySpy& cs) { cout << "c&" << endl; } // 2 3 1 2
// 5.按右值引用传递
void foo(CpySpy&& cs) { cout << "&&" << endl; } // X 1 X X
// 6.按常右值引用传递,很少见到返回常右值的变量,所以用处不大
void foo(const CpySpy&& cs) { cout << "c&&" << endl; } // X 2 X 1
#endif
int main()
{
// 非常量
CpySpy cs1;
foo(cs1); //左值
foo(CpySpy()); //右值
// 常量
const CpySpy cs2;
foo(cs2); //常左值
foo((const CpySpy())); //常右值
}
/* 总结:
1.按值传递和按引用传递互不兼容
2.按值传递内部常和非常不兼容
3.按引用传递内部互相兼容,但优先级不同(见表,数字越小越优先,X表示不能匹配)
4.按引用传递中,只有(4.按常引用传递)可以匹配所有传参,所以选用它作为拷贝构造函数
5.匹配规则为:(首先匹配完全匹配的)->(非常量限定可以匹配到常量限定)->(右值引用可以匹配到左值引用) */