有人可以用非常小的词语向我解释差异吗?我从来没有理解这一点,在我目前的项目中非常困惑。我想要做的是修复此代码:
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?
}
现在我的编译器告诉我这是对局部变量的引用,但它不会让我转向返回指针,因为它们与引用有某种不同。然后,我也在研究一个set类,它应该保存对抽象类对象的引用或指针。我完全糊涂了。任何帮助将不胜感激。
答案 0 :(得分:2)
首先,你的签名是错误的。它应该是:
Multinumber Pairs::operator+(const Multinumber &rhs) const;
operator+
应返回一个新对象,而不是对任一参数的引用。
至于引用和指针之间的区别,这个detailed question就在SO上。它涵盖了所有基础知识和一些基础知识。
答案 1 :(得分:1)
你看起来很困惑:)好吧,所以:
本质上,指针只是一个存储另一个变量地址的变量。例如,假设我有一个名为int
的{{1}},我可以将其地址存储在指针i
中:
p
如果我想改变它指向的东西(即它存储的地址的变量),我只是分配给int i = 23;
int *p = &i; // p has type int* (pointer to int) and stores &i (the address of i)
- 这是用来表示指向的东西的语法。在这种情况下,*p
指的是*p
。因此:
i
我可以重新分配指针(即指向其他东西)只需分配给*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
。引用必须始终引用实际对象。这种差异对于实现者来说很重要,因为他们可以使用指针来实现Maybe类型,即如果指针不是0
,则使用指向对象,否则执行其他操作。他们不能用引用做同样的事情。
希望关于指针和参考文献清楚明白!
现在,关于你的NULL
- 加法运算符的目的是添加两个对象并返回表示其总和的新对象。所以,如果我有一个2D矢量类型,我可能会为它写一个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!
}
不再存在于运算符的末尾,因此返回的指针最终将指向无效位置。底线 - 不要尝试任何花哨的东西,在这种情况下按价值回报。
答案 2 :(得分:0)
指针有一些对象所在的地址。引用是指针的别名,这意味着您不必取消引用它。但用法类似 - 不要复制对象,只能使用原点。
您将变量toreturn
作为局部变量,这意味着编译器在方法结束时为此对象生成析构函数。所以你试图返回被破坏的物体。