0
#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并将其保存在 objectbar中。

输出向我表明,赋值运算符在复制和获取新对象的值方面都没有发挥作用。我已经关注了这个链接

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

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

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

4

3 回答 3

3

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

但问题是您不了解引用 - 该成员Bar::x只是另一个变量的别名。给它分配一些东西也会修改原来的东西。

于 2013-01-15T15:05:27.797 回答
3

引用可能会令人困惑。const指针也可以。我将尝试通过同时谈论他们两个来澄清事情。我能说什么,我是个乐观主义者。

首先,const指针。

我们将从一个名为 的类开始Foo。我们可以有一个指向这个类的指针——一个Foo*. 我们可以有一个指向const此类实例的指针——a Foo const*。我们可以有一个const指向const这个类的非实例的指针——a Foo*const

AFoo const*是一个指针,您可以更改为无法更改的数据。

AFoo*const是您无法更改的指针,指向您可以更改的数据

我假设你明白了。毕竟,我是一个乐观主义者。接下来,让我们看看参考资料。

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

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

现在,它不止于此。有一些语法糖。当您创建对另一个变量的引用时,它会&自动执行 - 所以当您执行 a 时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指针”部分——分配给引用会修改指向的事物。

我对初始化和赋值如何与引用的不同含义的个人名称是“引用语义”,而不是“指针语义”,其中初始化和赋值都会改变所指向的东西。在“引用语义”中,初始化选择所指向的事物,赋值改变所指向事物的状态。

这非常令人困惑,我希望我能以不同的方式帮助它混淆。

于 2013-01-15T15:55:08.437 回答
0

内部与x中称为“x1”的变量相同。 这就是引用的作用——它们接受一个变量并给它另一个名称,您可以使用它来引用它。 无论您以这个新名称对该变量执行什么操作,都与使用任何其他名称执行此操作相同。barmain

首先,之后

Bar bar = Bar(x1);

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

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

线

bar = Bar(x2);

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

线

bar.x = 5;

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

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

于 2013-01-15T16:08:30.437 回答