C++ 的传参方式有 fun(T t)
fun(T* t)
fun(T& t)
fun(T&& t)
返回类型有T fun()
T& fun()
T* fun()
下面分别来讲下我对于传参的四种方式的理解。
fun(T t)
采用这种方式 表明T 会被复制进来函数体内部,传入的参数会执行拷贝操作函数,同时 t的生命周期是该函数体。
fun(T* t)
采用这种方式 表明 传进来一个t的指针,生命周期是依赖于传入的参数,不会执行拷贝操作。
fun(T& t)
采用这种方式 表明 传进来一个t的引用,生命周期是依赖于传入的参数,不会执行拷贝操作。同 fun(T* t)
fun(T&& t)
采用这种方式 表明 传进来一个t的右值引用,所谓右值引用我在这里举个栗子,当然后面也会再讲 int i = 0;
其中i
为左值,0为右值 ,右值引用就是不依赖于之前的生命周期,自己开辟一个内存空间盛放t 并且释放之前的传入参数。
下面用代码来进行验证,上述说法是否正确【在编写的时候注意注释掉相应位置处的代码,保证编译成功】
#include <stdio.h>
#include <iostream>
#include <unistd.h>
class T {
public :
T(){
std::cout<<"构造函数"<<count<<std::endl;
}
~T(){
std::cout<<"析构函数"<<count<<std::endl;
}
T(const T& t){
std::cout<< "拷贝构造函数"<<count<<std::endl;
}
T& operator= (const T &t){
std::cout<< "赋值操作符"<<count<<std::endl;
}
void countPP(){
count ++;
}
void printData(){
std::cout<< "我是打印"<<count<<std::endl;
}
private:
int count =0;
};
//void fun(T t ){
// std::cout<< "调用fun(T t )"<<std::endl;
// t.countPP();
// t.printData();
//}
//void fun(T* t){
// std::cout<< "调用fun(T* t )"<<std::endl;
// t->countPP();
// t->printData();
//}
//void fun(T& t){
// std::cout<< "调用fun(T& t )"<<std::endl;
// t.countPP();
// t.printData();
//}
void fun(T&& t){
std::cout<< "调用fun(T&& t )"<<std::endl;
t.countPP();
t.printData();
}
FunParam::FunParam()
{
//T* t = new T();
//std::cout<< "第1种方式"<<std::endl;
//fun(*t);
//std::cout<< "第2种方式"<<std::endl;
//fun(t);
//std::cout<< "第3种方式"<<std::endl;
//fun(*t);
std::cout<< "第4种方式"<<std::endl;
fun(T(std::move(*t)));
//t->printData();
}
复制代码
关于输出
构造函数0
第1种方式
拷贝构造函数0【注意这里】
调用fun(T t )
我是打印1
析构函数1【该析构是函数内复制出来的对象】
我是打印0
复制代码
关于
构造函数0
第2种方式
调用fun(T* t )
我是打印1
我是打印1 【在函数里面的修改会印象函数外的对象】
复制代码
关于
构造函数0
第3种方式
调用fun(T& t )
我是打印1
我是打印1 【和传递指针是相同的】
复制代码
关于
构造函数0
第4种方式
拷贝构造函数0
调用fun(T&& t )
我是打印1
析构函数1
我是打印0
复制代码
关于返回值类型
T fun()
传递的是对象,不会触发任何函数
T& fun()
传递的是引用,会调用拷贝构造函数,
T* fun()
传递的是指针,依赖于函数体内部对象的生命周期,
下面用代码进行验证
T* fun(){
std::cout<< "调用 T* fun"<<std::endl;
T t ; //栈上,方法结束,则释放
return &t;
}
//T fun(){
// std::cout<< "调用 T fun"<<std::endl;
// T t ;
// t.countPP();
// t.printData();
// return t;
//}
//T& fun(){
// std::cout<< "调用 T& fun"<<std::endl;
// T t ;
// t.countPP();
// t.printData();
// return t;
//}
FunParam::FunParam()
{
//测试返回类型
T* t = fun();
if(t){
std::cout<< "有值"<<std::endl;
}else{
std::cout<< "无值"<<std::endl;
}
// T t = fun();
// t.countPP();
// t.printData();
}
复制代码
关于
调用 T* fun
构造函数0
析构函数0
无值
复制代码
关于
调用 T fun
构造函数0
我是打印1
我是打印2
析构函数2
复制代码
关于
调用 T& fun
构造函数0
我是打印1
析构函数1
拷贝构造函数0 【这个地方会触发拷贝函数!!!】
我是打印1
析构函数1
复制代码