为非静态引用成员类编写`operator =`

时间:2013-01-15 15:03:56

标签: c++ inheritance reference operator-keyword copy-constructor

#include <iostream>

class Bar
{
    protected:

public:
        int & x;
        Bar(int & new_x)
        :x(new_x)
        {}
        Bar & operator = (const Bar toCopy)
        {
            x = toCopy.x;
            return *this;
        }
};

int main()
{
    int x1(1);
    int x2(2);

    Bar bar = Bar(x1);
    std::cout << bar.x << std::endl;

    bar = Bar(x2);
    std::cout << bar.x << std::endl;

    bar.x = 5;
    std::cout << bar.x << std::endl;

    std::cout << x1 << std::endl;
    std::cout << x2 << std::endl;

}

输出结果为:

1
2
5
5
2

我要做的是复制 x并将其保存在对象bar中。

输出告诉我,赋值运算符在复制和获取新对象的值方面都没有完成它的魔力。我跟着this link

x更改为值而不是引用是不可能的,因为真实程序x是一个抽象类。

请尽可能避免使用堆分配。

修改: 我意识到我刚刚使用了C ++语言。我想向所有说“C ++ ian”的计算机道歉。我的动机是在堆栈上分配一个成员抽象变量。据我所知,它不能在堆栈上完成,因为派生类的大小在编译时是未知的。 好的......我总共n00b ......(没有sh * t,Sherlock!)。 “有效的C ++编程”@rhalbersma是必备的。它包含必需品,但你不会在任何地方找到它们(复制结构,复制初始化程序),..无论如何都在一个地方。

3 个答案:

答案 0 :(得分:3)

Bar bar = Bar(x1);不是作业,而是复制初始化。它调用复制构造函数,而不是复制赋值运算符。

但问题是你不理解引用 - 成员Bar::x只是另一个变量的别名。为其分配内容也会修改原始内容。

答案 1 :(得分:3)

参考文献可能令人困惑。所以const指针也可以。我会试着通过同时谈论它们来解决问题。我能说什么,我是一个乐观主义者。

首先,const指针。

我们将从一个名为Foo的类开始。我们可以指向这个类 - Foo*。我们可以指向此类的const实例 - Foo const*。我们可以使用const指针指向此类的非const实例 - Foo*const

Foo const*可以更改为无法更改的数据的指针。

Foo*const是您无法更改为可以更改的数据的指针。

我会假设你有这个。毕竟,我是一个乐观主义者。接下来,让我们看一下参考文献。

虽然引用是别名,但有时候在一个事物具有其他类型的具体实现的世界中考虑它们会有所帮助。

Foo&类似于Foo*const - 指向您可以更改的Foo实例的不可更改“指针”。所以你所谈论的Foo总是相同的,但你可以改变它的状态。

现在,它不止于此。有一些语法糖。当您创建对另一个变量的引用时,它会自动执行& - 所以当您执行Foo& f = a;时,这类似于Foo*const f = &a;

其次,当您使用.时,它与指针大小写中的->相同。 (对于(大多数?)其他运营商也是如此)

第三,当你进行赋值时,它显然不能改变指针的值 - 因为它是const - 而是它改变了指向的东西的值。因此,Foo& f = a; a = b;相当于Foo*const f = &a; *f = b;

当您使用operator=时,它会将指向的内容分配给而不是指针。但是,当您初始化它时,即使您有operator=令牌,它也不会使用=

初始化与一般的赋值不同,初始化和赋值中&引用和*指针所发生的语义非常不同。

Foo& f = a; f = b;完成两件完全不同的事情。引用的初始化初始化“const指针”部分 - 对引用的赋值修改指向的事物。

我的个人名称,关于初始化和赋值如何表示引用的不同内容是“引用语义”,而不是“指针语义”,其中初始化和赋值都改变了指向的内容。在“引用语义”中,初始化选择指向的东西,并且赋值改变指向的东西的状态。

这非常令人困惑,我希望我以不同的方式让它变得混乱。

答案 2 :(得分:0)

x内的bar main中名为“x1”的相同的变量
这就是引用所做的 - 它们接受一个变量并给它另一个名称,你可以用它来引用它 无论你使用这个新名称对该变量做什么都与在任何其他名称下进行该变量相同。

首先,

之后
Bar bar = Bar(x1);

(这是复制初始化,不是分配)
“bar.x”指的是与右侧匿名对象内部的“x”相同的变量,而“x”又是main中“x1”的不同名称。

此后,名称“bar.x”指的是与名称“x1”相同的变量。

该行

bar = Bar(x2);

将匿名对象的x(与x2相同的变量)的值(即2)分配给bar内名为“x”的变量,但是在main中名称为“x1”。

该行

bar.x = 5;

然后将值5赋给名称为“bar.x”的变量,该变量与main中的“x1”变量相同。

你不能让它引用不同的变量 如果你想要一些可以引用不同变量的东西,你必须使用指针。