C++之我见方法参数类型与返回类型

本文深入解析C++中四种传参方式:按值、按指针、按引用和按右值引用,以及三种返回值类型:按对象、按引用、按指针的区别与应用场景,通过实例代码验证每种方式的行为特征。

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
复制代码

转载于:https://juejin.im/post/5cbad5556fb9a068a93f199d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值