指针和参考
Pointers & Reference
所以,我了解指针是什么,引用某个东西意味着什么,并且对这个"堆"有一个模糊的理解。当我们使用这些概念引入函数和类时,我开始失去对事物的控制,例如发送指针、返回指针等。
如果通过引用和传递指针本质上执行相同的功能,那么使用其中一个指针的优势是什么?两者本质上都是通过引用传递和在被调用函数之外操作对象。
因此,通过参考:
#include <iostream>
class student{
public:
int semesterHours;
float gpa;
};
void defRefS( student &refS );
void defPointerS( student *Ps );
void defValueS( student cS );
int main()
{
student s;
defRefS(s); //Here,
std::cout << "nBack in main we have " << s.semesterHours << " hours";
std::cout << "nBack in main the GPA is: " << s.gpa;
student *Ps = &s;
defPointerS(&s); //And here is where I get confused
std::cout << "nBack in main we have " << s.semesterHours << " hours";
std::cout << "nBack in main the GPA is: " << s.gpa;
defValueS(s);
std::cout << "nBack in main object S has: " << s.semesterHours << " hours";
std::cout << "nBack in main object S has: " << s.gpa << " GPAnn";
}
void defRefS( student &refS ) //Passing by reference to object
{
refS.gpa = 4.0;
refS.semesterHours = 12;
std::cout << "n------------- Reference Function ------------";
std::cout << "nnObject S has: " << refS.semesterHours << " hours";
std::cout << "nObject S has: " << refS.gpa << " GPA";
}
void defPointerS( student *Ps ) //Passing a pointer to the object
{
Ps->gpa = 5.0;
Ps->semesterHours = 14;
std::cout << "nn------------- Pointer Function ---------------";
std::cout << "nnNow object S has: " << Ps->semesterHours << " hours";
std::cout << "nNow object S has: " << Ps->gpa << " GPA";
}
void defValueS( student cS ) //Passing the object by value
{
cS.gpa = 100;
cS.semesterHours = 50;
std::cout << "nn------------- Value Function ------------------";
std::cout << "nnObject S has: " << cS.semesterHours << " hours";
std::cout << "nObject S has: " << cS.gpa << " GPA";
}
通过引用传递本质上允许符号相似,因为我想,在所有方面,refS
都是s
对象。因此,这带来了一种使用函数操作对象的简单方法。
传递指针很容易理解。它只是指向对象的指针。尽管在上面的代码中如何:
void defRefS( student &refS );
void defPointerS( student *Ps );
void defValueS( student cS );
是否所有这些函数都只定义为与学生类一起使用?那么,这些函数只能将对象的引用、指针和值传递给这个特定的类?
defRefS(s); //Here,
defPointerS(&s); //And here is where I get confused
defValueS(s);
如果通过引用传递,难道不应该传递对象的地址吗?因此,对我来说,自从在引用函数中传递指针函数的参数以来,它做了更多的事情。
函数defPointerS
被定义为接受指针;我在给它发地址?
我猜您刚刚开始使用C++。不要担心堆,这是一个较低级别的概念,稍后您将了解它。如果您真的感兴趣,new
操作符和malloc
会在堆上分配内存(new实际上也会调用对象的构造函数,为您提供一个动态对象)。你可以把它想象成一个大空间,在那里你可以放你以后想要的东西)。
关于指针和引用,它们在大多数情况下是可互换的(正如您所了解的)。它只是取决于您想要如何构建代码。
在C++中,指针无处不在,人们通常传递指针而不是通过引用传递。指针使用频率更高的原因之一是动态内存分配的工作方式(new
运算符或malloc
)——它返回一个指针——而且你做了很多。所以通常你会通过给定的指针对对象进行操作。
在复制构造函数或定义运算符时,极少数情况下绝对必须使用引用。
我可能遗漏了一些案例,但这就是要点。
你会混淆与号(&)的两种用法。在一种情况下,它是一个运算符,而在另一种情况中,它是声明类型的一部分。
int x = 5;
int* y = &x; // (1) Here it's an operator
int& z = x; // (2) Here it's part of the type of y
在上面的第(1)行中,我们声明并定义了一个名为y
的变量,该变量的类型为pointer to int
。这意味着变量y
应该包含类型为int
的变量的地址。要获取变量的地址,可以使用&
作为运算符。因此,&x
是x
的地址,我们将其存储在指针中。CCD_ 15现在是指向CCD_ 16的指针。
在第(2)行中,我们定义了一个名为z
的变量,该变量的类型为reference to int
。由于我们将x绑定到这个引用,这意味着我们可以使用z
作为x
的另一个名称。修改z
将修改x
(以及y
指向的值!)。
因此,当你有一个接受指针的函数,比如void func(int* p)
,你需要给它传递int的地址。要做到这一点,你要么直接传递指针,要么接受int
:的地址
int x = 5;
func(&x);
如果您有一个接受引用的函数,比如void func(int& r)
,那么您只需要向它传递一个int
。参考文献将参考相同的int
。
int x = 5;
func(x);
这些可以以类似的方式使用:将参数传递给函数,以便函数可以对其进行修改或避免复制。但是,指针参数也允许将空指针传递给函数。这对引用不起作用,因为引用必须始终绑定到某个对象。此外,引用一旦绑定,就不能反弹到其他对象。
引用通常更方便,并且不依赖于C风格的指针操作。在C++中,您通常希望尽可能使用引用,必要时使用指针。有关详细信息,请参阅C++常见问题解答。
当您在函数/类型定义中使用字符&
时(如在void defRefS( student &refS );
或student &refS
中),您正在定义引用。该值将是一个参考。
当您在对象(变量)上使用相同的运算符(即:相同的字符&
)时,您将获得该特定对象的地址(如在student *Ps = &s;
或defPointerS(&s);
中)。该值将是一个指针。
还困惑吗?然后不要读下一句。运算符&
也是按位AND,当在语句中时,例如0x1 & 0xFF
产生1。返回值将是一个与语句中最大整数大小相当的整数。
使用其中一个的优势是什么
使用引用来传递函数的输入参数是有充分理由的:引用永远不能为NULL,所以不需要检查指针是否指向任何位置。
使用指针来传递函数的输入参数是有充分理由的:您可以使用指针算术,这样您就可以传递数组(这在c++中是不推荐的)。因此,在大多数情况下,最好坚持参考。
如果通过引用传递,难道不应该传递对象的地址吗-不,你按原样传递一个对象。参数附近的"与"表示该参数引用对象而不复制。
函数defPointerS被定义为接受指针;我在给它发地址-运算符"&"在应用于r值时生成指向对象的指针。
当您有student s;
变量,并且您想将其传递给函数f
,该函数接受类型为student
(通过值传递)或student&
(通过引用传递)的参数时,您只需调用f(s)
。如果按值传递s
,则会创建s
的副本,并在函数体中使用s
的副本。如果通过引用传递,则直接使用对象s
。引用不能为NULL,这在许多情况下都是非常有利的。
当这个参数的类型是student*
(也通过引用传递)时,您调用f(&s)
,因为指针需要用它将指向的地址初始化。
您还应该检查:指针与引用
对于初学者,请参阅C++中指针变量和引用变量之间的区别是什么?。
当通过引用传递变量时,您可以将其视为隐式获取地址,因此不必编写&,但它仍然在为你做这件事(这就是为什么如果你为引用参数传递一个像"5"这样的常数,你会得到一个错误)。它还隐式地在函数内部取消引用它,所以您也不必写"*"。
"函数defPointerS被定义为接受指针;我要给它发送地址?"指针是一个地址(或者更准确地说,是一个存储内存地址值的变量)。
"那么,这些函数只能将对象的引用、指针和值传递给这个特定的类?"这些类型表明,如果你试图将另一个类的实例传递给这个函数,你会收到编译器错误。然而,C++并没有强制执行类型安全性,您可以绕过它,强制它使用"relpret_cast"将指针传递到其他类型的对象。在大多数情况下,这是行不通的。
- 我可以有一个 ELI5 作为参考和指针以及何时使用它们吗?
- 类的方法和对象。参考?智能指针?简单的初始化?
- 我正在学习C++,我不能使用指针访问参考吗?(举个例子)
- 使用指针向量到参考向量是非法的吗?
- 函数参数绑定通过参考与传递指针传递数组的规则
- 参考参考static_cast的成本和指向指针static_cast的指针
- 函数采用原始指针试图通过错误msg中概述的参考来接受指针
- 为什么即使传递给函数作为参考,指针也未被分配
- 为什么通用参考概念不适用于函数指针的地图插入
- 是指代指针正交的参考文献
- 超载函数既不按值,也不是通过参考来对象,而是将撤销的指针换成对象
- 从参考中获取的指针可以在定义明确的C 中取无效
- 指针与参考示例,在什么情况下更好
- 为什么要拿参考的地址给我一个第二等级的指针
- 如何提升::序列化指针和参考
- 在范围外丢失指针参考
- 为什么动态演员只能与参考和指针一起使用
- 为什么该函数不会获得动态数组?(我正在使用指针和参考)
- 如果我创建一个模板类,而不是其他我将参考(指针)发送到该类的类
- 通过静态局部变量的参考/指针返回