引言
最近在看代码时候,又因为这个问题卡了一下,所以再详细分析下
我遇到了类似这样的函数
代码语言:javascript复制bool MyClass(sTunnl& sData, sTunnl* sBase)
{
// 代码
}
现在解释下
第一个参数,传进来的这个东西,是个对象引用,起别名叫做sData,所以&sData
第二个参数,传进来的这个东西,是个sTunnl对象的指针,*是解引用,相当于是把传进来的东西放在*sBase里面
使用的话,那就sData.get();
例子
代码语言:javascript复制#include <iostream>
class MyClass {
public:
int x;
MyClass(int val) : x(val) {}
void print() { std::cout << "Value: " << x << std::endl; }
};
int main() {
MyClass obj(10); // 创建一个 MyClass 对象
MyClass &ref = obj; // 创建一个对象引用
MyClass *ptr = &obj; // 创建一个对象指针
obj.print(); // 直接访问对象
ref.print(); // 通过对象引用访问对象
ptr->print(); // 通过对象指针访问对象
return 0;
}
在这个示例中,我们首先创建了一个 MyClass 对象 obj。然后,我们创建了一个指向该对象的对象引用 ref 和一个指向该对象的对象指针 ptr。
接下来,我们分别使用三种方式访问该对象:直接访问、通过对象引用访问和通过对象指针访问。你可以看到,无论使用哪种方式,都可以成功访问该对象。
那*ptr->print()对吗,*ptr和ptr的意思是一样的吗
*ptr->print() 是不正确的。ptr->print() 是正确的写法,它等价于 (*ptr).print()。
ptr 是一个指向对象的指针,而 *ptr 表示指针所指向的对象。因此,ptr 和 *ptr 的意思是不同的。
当你想通过指针访问对象的成员时,可以使用 -> 运算符。例如,如果你想通过指针 ptr 访问对象的 print 方法,可以这样写:
代码语言:javascript复制ptr->print();
这等价于先解引用指针,然后再访问对象的成员:
代码语言:javascript复制(*ptr).print();
那*ref.print()可以吗
不,*ref.print() 是不正确的写法。如果想通过对象引用访问对象的成员,应该直接使用 . 运算符。例如,如果你想通过对象引用 ref 访问对象的 print 方法,可以这样写:
代码语言:javascript复制ref.print();
由于对象引用本身就是对象的别名,因此无需对其进行解引用。可以直接像访问对象本身一样访问对象引用。
为什么对象指针需要解引用,而对象引用就不需要
对象指针和对象引用的工作方式不同。对象指针存储的是对象的地址,而不是对象本身。因此,当你想通过指针访问对象时,需要先解引用指针,才能获取指针所指向的对象。
例如,假设你有一个指向 MyClass 对象的指针 ptr。如果你想通过指针访问该对象的 x 成员,需要先解引用指针,然后再访问成员:
代码语言:javascript复制int a = (*ptr).x;
或者使用 -> 运算符简化代码:
代码语言:javascript复制int a = ptr->x;
而对象引用则不同。它本身就是对象的别名,因此无需进行解引用。你可以直接像访问对象本身一样访问对象引用。
例如,假设你有一个 MyClass 对象的引用 ref。如果你想通过引用访问该对象的 x 成员,可以直接这样写:
代码语言:javascript复制int a = ref.x;
为什么->运算符可以简化代码
-> 运算符是一种特殊的运算符,用于通过指针访问对象的成员。它可以简化代码,因为它允许你直接通过指针访问对象的成员,而无需先解引用指针。
例如,假设你有一个指向 MyClass 对象的指针 ptr。如果你想通过指针访问该对象的 x 成员,可以这样写:
代码语言:javascript复制int a = (*ptr).x;
但是这种写法比较繁琐,不够简洁。为了简化代码,你可以使用 -> 运算符:
代码语言:javascript复制int a = ptr->x;
这样,你就可以直接通过指针访问对象的成员,而无需先解引用指针。这样的代码更加简洁易读。
这是我画的表格来理解
没有->运算符的话
ptr | MyClass | get() |
---|---|---|
0x83484 | *ptr | (*ptr).get() |
有->运算符的话
ptr | MyClass | get() |
---|---|---|
0x83484 | ptr->get() |
所以有了运算符相当于写法上省了中间这一步
那运算符到底放在什么位置呢
有的人这样写int *a,有的人写成int* a
之所以出现差异C 是因为 C 之上添加了更强大的类型系统。
C 样式
C程序员通常从“价值”的角度思考,所以
int *pValue;
读作“pValue的解引用是一个整数”。
C 风格
而C 程序员在“类型”中思考
int* pValue;
读取“pValue 的类型是指向 int 的指针”。
当然,编译器完全没有看到任何区别。
不过注意一个事情,就是定义多个变量时小心混乱
代码语言:javascript复制int* foo, bar; // foo will be int*, bar will be int
解决方案是,永远不要在同一行上声明多个变量
其实我个人是喜欢int *p这种的,因为这样我知道*p是表示一个地址