【问题标题】:Value inside object won't change after passing by reference通过引用传递后对象内部的值不会改变
【发布时间】:2020-04-05 14:12:03
【问题描述】:

为什么我通过引用传递了对象内部的值却没有改变。

class ref_test {
public:
    explicit ref_test(const int& a) : a(a) {};

    const int& get_a() noexcept { return a;}
private:
    const int a;
};

int main(int argc, char* argv[]) {

    int b = 10;
    ref_test r(b);

    b = 15;
    std::cout << r.get_a() << std::endl;
    std::cout << b << std::endl;

    return 0;
}

输出:
10
15

据我了解,我将内存位置传递给不允许更改它的对象(因为它被标记为 const)。如果我在传递后更改值,则内存位置内的值应该改变,因此也应该改变对象内的值。 如果这是真的,那么通过引用传递给对象应该是不安全的,因为之后值可能会被更改。那么,按值传递给对象是不是更好?

【问题讨论】:

    标签: c++ object reference


    【解决方案1】:

    类中的私有 int 不是引用。所以成员初始化器中的构造是复制参数。

    如果将成员变量改为

    int const &a;
    

    然后程序将打印15 15

    如果这不是您想要的行为,那么只需按值获取构造函数参数。

    【讨论】:

    • 我将私有成员变量更改为const int&amp; a,但这不会改变发布程序的输出。
    • 好的,我的 IDE 似乎有问题,奇怪。
    【解决方案2】:

    ref_test 类中,私有数据成员 a 没有引用类型

    const int a;
    

    如果您希望此数据成员具有引用类型,则必须编写

    const int &a;
    

    在这种情况下,数据成员a 将引用传递给类的构造函数的对象。

    要查看更改,请在重新分配变量 b 之前再插入一条输出语句。

    std::cout << r.get_a() << std::endl;
    b = 15;
    std::cout << r.get_a() << std::endl;
    

    另一种方法是使用标准类std::reference_wrapper

    这是一个演示程序。

    #include <iostream>
    #include <functional>
    
    class ref_test 
    {
    public:
        explicit ref_test(const int& a) : a(a) {};
    
        const int & get_a() noexcept { return a;}
    
    private:
        const int &a;
    };
    
    class ref_test2 
    {
    public:
        explicit ref_test2( const int& a ) : a(a) {};
    
        const int & get_a() noexcept { return ( a.get() );}
    
    private:
        std::reference_wrapper<const int> a;
    };
    
    int main() 
    {
        int b = 10;
        ref_test r(b);
    
        std::cout << r.get_a() << '\n';
        std::cout << b << '\n';
    
        b = 15;
    
        std::cout << r.get_a() << '\n';
        std::cout << b << '\n';
    
        std::cout << '\n';
    
        ref_test2 r2( b );
    
        std::cout << r2.get_a() << '\n';
        std::cout << b << '\n';
    
        b = 20;
    
        std::cout << r2.get_a() << '\n';
        std::cout << b << '\n';
    
        return 0;
    }
    

    程序输出是

    10
    10
    15
    15
    
    15
    15
    20
    20
    

    【讨论】:

    • wrapper有什么好处?
    • @SimonPio。它将允许绑定一个临时对象。
    猜你喜欢
    • 1970-01-01
    • 2016-09-27
    • 2018-03-04
    • 2017-10-21
    • 2012-02-14
    • 2020-08-11
    • 1970-01-01
    • 2011-09-27
    • 2013-06-27
    相关资源
    最近更新 更多