C++ 引用和指针之间的区别是什么?
有人能用很小的话向我解释一下这种区别吗?我从来没有理解过这一点,在我目前的项目中感到非常困惑。我正在尝试修复此代码:C++ 引用和指针之间的区别是什么?,c++,pointers,dynamic-memory-allocation,C++,Pointers,Dynamic Memory Allocation,有人能用很小的话向我解释一下这种区别吗?我从来没有理解过这一点,在我目前的项目中感到非常困惑。我正在尝试修复此代码: const Multinumber& Pairs::operator+(const Multinumber &rhs) const { const Pairs &_rhs = dynamic_cast<const Pairs &>(rhs); Pairs toreturn(_rhs.X_value+X_value,_rh
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?
}
const-Multinumber&Pairs::operator+(const-Multinumber&rhs)const
{
常量对&_rhs=动态投射(rhs);
成对返回(_rhs.X_值+X_值,_rhs.Y_值+Y_值);
return toreturn;//引用局部变量?是否修复此问题?
}
现在,我的编译器告诉我这是对局部变量的引用,但它不允许我将其转换为指针,因为它们在某种程度上与引用不同。然后,我也在处理一个集合类,它应该包含对抽象类对象的引用或指针。我完全糊涂了。任何帮助都将不胜感激。首先,您的签名是错误的。应该是:
Multinumber Pairs::operator+(const Multinumber &rhs) const;
operator+
应该返回一个新对象,而不是对两个参数的引用
至于引用和指针之间的区别,就在这里。它涵盖了所有的基础知识,还有一些。指针有一些对象所在的地址。引用是指针的别名,这意味着不必取消引用它。但是用法是相似的-不要复制对象,只使用原点
您将变量
toreturn
作为局部变量,这意味着编译器将在方法末尾为该对象生成析构函数。所以,您正试图返回已销毁的对象。您看起来确实很困惑:)好的,那么:
实际上,指针只是一个存储另一个变量地址的变量。例如,假设我有一个名为I
的int
,我可以将其地址存储在指针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
,表示它们没有指向任何东西。这只意味着它们包含地址0
。引用必须始终引用实际对象。这种差异对实现者来说可能很重要,因为他们可以使用指针来实现Maybe类型,也就是说,如果指针不是NULL
,那么就使用指向的对象,否则就做其他事情。他们不能对参考文献做同样的事情
希望这是明确的指针与参考
现在,关于您的
操作符+
——加法操作符的目的是添加两个对象并返回一个表示其和的新对象。因此,如果我有一个2D向量类型,我可能会为它编写一个操作符+
,如下所示:
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
在运算符末尾不再存在,因此返回的指针将指向无效位置。底线——不要做任何花哨的事情,在这种情况下按值返回。在您的情况下,引用是一个别名,并引用某个地址。但是,您引用了本地创建的toreturn
,然后尝试返回其引用,即使toreturn
的生命周期在函数返回时结束。您始终可以使toreturn静态
,但这似乎也不是一个好主意……实际上,您的签名也是错误的。它应该是Multinumber操作符+(const Multinumber&lhs,const Multinumber&rhs)
,或者可能是const Multinumber操作符+(const Multinumber&lhs,const Multinumber&rhs)
@wilhelmtell您声明的函数,@André声明method@Gaim对因为操作符+()
应该是一个自由函数。@wilhelmtell它不需要。它可以重新定义为方法。这是两个中的一个options@Gaim@MichaelAaronSafyan这不是风格的问题,当然也不是品味的问题。这是一个功能问题。如果Multinumber
可以从int(例如,Multinumber
有一个接受int的构造函数)转换而来,那么表达式1+Multinumber()
只有在operator+()
是自由函数时才起作用。另外,如果operator+()
返回一个非常量,则表达式Multinumber()+Multinumber()=Multinumber()
是有效的。这是有用的还是正确的是有争议的,可能与上下文有关。谢谢!无论如何,按值返回的问题是,我必须返回一个类型为Multinumber的对象,因为我使用的是多态性,并且基类的运算符+被定义为返回一个Multinumber。复杂遗传多重麻木