You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中能否直接传递栈上内联创建的类实例作为引用参数?

问题原因

Print(MyClass(7))执行失败的核心原因是:C++不允许将临时对象绑定到非const的左值引用。MyClass(7)是临时创建的右值对象,而你的Print函数参数是MyClass&(非const左值引用),编译器会直接拒绝这种绑定操作。

而Print(myObj)可行是因为myObj是栈上的左值;Print(*(new MyClass(5)))可行是因为new返回的指针解引用后属于左值范畴,哪怕它是堆上的对象。

解决方法

有两种常用方式可以实现传递临时对象的需求:

方法1:将参数改为const左值引用(推荐)

把Print的参数改成const MyClass&,同时将GetIVal成员函数声明为const(因为const引用指向的对象只能调用const成员函数),这样既可以接收普通左值,也能接收临时右值对象:

#include <iostream>

class MyClass
{
    int m_i;
    
public:
    MyClass(int i) { m_i = i; }
    // 声明为const成员函数,确保能在const对象上调用
    int GetIVal() const { return m_i; }
};

// 参数改为const左值引用
void Print(const MyClass& refObj)
{
    std::cout << refObj.GetIVal();
}

int main() {
    std::cout << "Hello world!\n";
    
    MyClass myObj(3);
    Print(myObj); // 仍然可行
    Print(*(new MyClass(5))); // 仍然可行
    Print(MyClass(7)); // 现在可行

    return 0;
}

这是C++处理此类场景的标准方案,const左值引用会自动延长临时对象的生命周期,直到引用的作用域结束,同时能保证不会意外修改传入的对象。

方法2:使用右值引用参数

如果你的Print函数专门用于处理临时对象,或者需要修改临时对象,可以将参数改为右值引用MyClass&&:

#include <iostream>

class MyClass
{
    int m_i;
    
public:
    MyClass(int i) { m_i = i; }
    int GetIVal() { return m_i; }
};

// 参数改为右值引用
void Print(MyClass&& refObj)
{
    std::cout << refObj.GetIVal();
}

int main() {
    std::cout << "Hello world!\n";
    
    MyClass myObj(3);
    Print(std::move(myObj)); // 需要用std::move将左值转为右值才能传递
    Print(std::move(*(new MyClass(5)))); // 同样需要std::move转换
    Print(MyClass(7)); // 可行

    return 0;
}

这种方法的局限性在于,普通左值无法直接传递,必须通过std::move转换为右值,因此如果需要同时支持左值和临时对象,方法1的通用性更强。


内容的提问来源于stack exchange,提问作者Tiger Galo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 05:47:05