Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 引用和指针之间的区别是什么?_C++_Pointers_Dynamic Memory Allocation - Fatal编程技术网

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。复杂遗传多重麻木