1

有人可以用非常简短的语言向我解释其中的区别吗?我从来没有理解这一点,并且在我目前的项目中非常困惑。我想要做的是修复这段代码:

const Multinumber& Pairs::operator+(const Multinumber &rhs) const
{
    const Pairs &_rhs = dynamic_cast<const Pairs &>(rhs);
    Pairs toreturn(_rhs.X_value+X_value,_rhs.Y_value+Y_value);
    return toreturn; //reference to local variable? fix this?
}

现在我的编译器告诉我这是对局部变量的引用,但它不会让我将 toreturn 变成指针,因为它们在某种程度上与引用不同。然后,我还在研究一个集合类,它应该包含对抽象类对象的引用或指针。我完全糊涂了。任何帮助将非常感激。

4

3 回答 3

2

首先,你的签名是错误的。它应该是:

Multinumber Pairs::operator+(const Multinumber &rhs) const;

operator+应该返回一个新对象,而不是对任一参数的引用。

至于引用和指针之间的区别,这个详细的问题就在这里。它涵盖了所有基础知识和一些基础知识。

于 2010-11-25T22:55:53.853 回答
1

你似乎很困惑:) 好的,所以:

本质上,指针只是一个存储另一个变量地址的变量。例如,假设我有一个int被调用的i,我可以将它的地址存储在一个指针中p

int i = 23;
int *p = &i;    // p has type int* (pointer to int) and stores &i (the address of i)

如果我想改变它指向的东西(即它存储的地址的变量),我只需分配给它*p——这是用来表示所指向的东西的语法。在这种情况下,*pi。因此:

*p = 9;     // sets i to 9 (since *p is i)

我可以通过分配来重新定位指针(即使其指向其他东西)p,即

int j = 84;
p = &j;     // store j's address in p, overwriting what was there before (i.e. i's address)
*p = 18;        // sets j to 18 (since *p is now j)

现在,参考略有不同。引用为变量创建别名:

int i = 23;
int& r = i;     // r has type int& (reference to int) and refers to i

请注意,引用可能以指针的形式实现(或者它们可能不会,特别是当编译器开始优化事物时),但这与编程的角度无关——这里对我们来说重要的是语言的工作方式。

如果您想更改所指的内容(即i在这种情况下),您只需执行以下操作:

r = 9;      // sets i to 9 (since r is an alias for i)

与指针不同,引用不能被重新定位。如上所示,分配给r更改您所指的事物 ( i),而不是引用本身。此外,由于引用不能被重新定位,它们必须立即初始化。这不是指针的情况。换句话说:

int *p;     // legal
int& r;     // bad

最后一个基本区别是指针可以是NULL,表示它们没有指向任何东西。这只是意味着它们包含地址0。引用必须始终引用实际对象。这种差异对实现者来说可能很重要,因为他们可以使用指针来实现 Maybe 类型,即如果指针不是NULL,则使用指向的对象,否则执行其他操作。他们不能对引用做同样的事情。

希望关于指针与引用的问题很清楚!


现在,关于您的operator+-- 加法运算符的目的是添加两个对象并返回一个表示它们总和的新对象。所以如果我有一个二维向量类型,我可能会operator+为它写一个如下:

Vec2 operator+(const Vec2& lhs, const Vec2& rhs)
{
    return Vec2(lhs.x+rhs.x, lhs.y+rhs.y);
}

在您的代码中,您试图toreturn通过引用返回一个本地对象——这不起作用,因为toreturn在运算符的末尾不再存在。相反,您应该在此处按值返回。顺便说一句,如果你试图返回一个指针,你会遇到同样的问题,例如

Vec2* operator+(const Vec2& lhs, const Vec2& rhs)
{
    Vec2 result(lhs.x+rhs.x, lhs.y+rhs.y);
    return &result; // bad!
}

在该代码result中,运算符末尾不再存在,因此您返回的指针最终将指向无效位置。底线——不要尝试任何花哨的东西,在这种情况下按值返回。

于 2010-11-26T03:21:20.513 回答
0

指针在对象所在的位置有一些地址。并且引用是指针的别名,这意味着您不必取消引用它。但用法是相似的——不要复制对象,只使用原点。

您将变量toreturn作为局部变量,这意味着编译器会在方法结束时为此对象生成析构函数。所以你试图返回被破坏的对象。

于 2010-11-25T22:59:01.393 回答