c++中的参考更新

Reference update in C++

本文关键字:更新 参考 c++      更新时间:2023-10-16

我有一个关于c++中引用更新的简单问题。考虑以下c++代码:

class A
{
    int b;
    public:
    int& setb();
    int getb();
    A();
    A &operator= (const A &t)
    {
        cout<<"Assignment called"<<endl;
    }
    A(int i):b(i) {
        cout<<"Copy contructor called"<<endl;
    }
};
int A::getb()
{
    cout<<this->b<<endl;
}
int& A::setb()
{
    return b;
}
A::A()
{
    cout<<"constructor called"<<endl;
}
int main()
{
    A a;
    cout<<"About to set reference"<<endl;
    a.setb()=5;
    a.getb();
    return 0;
}

当我通过引用更新b时,如何复制值?是否有被调用的默认复制构造函数?

理解这一点最简单的方法是,至少对我来说,想象您使用的是指针,而不是引用:

int* A::setb()
{
    return &b;
}

现在如果你这样做:

*(a.setb())=5;

很明显发生了什么。引用做完全相同的事情,但没有所有的*&的繁文缛节。赋值/复制构造函数与此无关。现在,如果您的字段不是int,而是某种自定义类型,那么将调用类型的赋值操作符。你可以在赋值中做任何你想做的。

一个有趣的技巧是,您的setb可能返回一个"智能引用"类型,实际上更新b,但可能做更多的事情:

class TwoIntsRef {
public:
    TwoIntsRef(int &a, int &b) :
        a(a),
        b(b)
    {}
    TwoIntsRef& operator=(int c)
    {
        cout << "TwoIntsRef Assignment called" << endl;
        a = c;
        b = c;
        return *this;
    }
private:
    int &a;
    int &b;
};

然后你这样做:

TwoIntsRef A::setb()
{
    return TwoIntsRef(b, c);
}

:

a.setb() = 5;

现在它同时设置bc

这实际上是一个非常有用的技巧,可以做很多事情。在我的一个项目中,我必须移植严重依赖Big Endian字节顺序的遗留代码。为了让它在Little Endian硬件上工作,我必须用智能引用替换所有内存访问,智能引用会自动交换字节。这不是一个非常有效的方法,但在这个特定的项目中,这是唯一可行的方法。

不,当您通过引用更新b时,不会调用隐式或显式定义的复制构造函数。

Copy构造函数在定义(尚未分配内存)时调用,您正在为对象赋值

交货

A obj = a;

赋值操作符将被调用,当对象已经定义(内存已经分配),你想改变对象的字段。

通过您的代码,我看到您使用了c++编译器的默认复制构造函数。它将使用类的每个非静态成员的复制构造函数。注意,在您的例子中生成的构造函数看起来像:

A(const &A other) 
:   b(other.b) 
{}

,在以下情况下它将被调用:

A a;
...
A b = a;
...
A c(a);

换句话说,当您从同一类中的其他对象构造新对象时,将调用复制构造函数。你的int构造函数不是复制构造函数。

第二,为什么你把b设为私有,而每个人都可以通过setb()修改它?我认为实现setb()的更好方法是:

void A::setb(const int& val) {
    b = val;
}