示例:箭头操作符的使用及其重载:
#include <iostream>
#include <string>
class Entity
{
public:
int x;
public:
void Print() const {std::cout << "Hello" << std::endl;}
};
class ScopedPtr
{
private:
Entity* m_Obj;
public:
ScopedPtr(Entity* entity)
: m_Obj(entity)
{
}
~ScopedPtr()
{
delete m_Obj;
}
const Entity* operator->() const
{
return m_Obj;
}
};
int main()
{
Entity e;
e.x = 1;
e.Print();
Entity* ptr = &e;
ptr->x = 2;
ptr->Print(); //等价于:(*ptr).Print();
const ScopedPtr* entity = new Entity();//const指针只能调用const型的成员函数
entity->Print();
return 0;
}
我们主要分析以下第41、42行代码,当我们将其替换成Entity* entity = new Entity(); entity->Print();
时,编译器并不会报错,因为ScopedPtr中并没有m_Obj,我们定义的是Scopedptr型的entity,编译器无法找到Entity的成员函数Print,所以我们需要重载->
。
示例:箭头操作符的应用(获取内存中某个成员变量的偏移量)
#include <iostream>
#include <string>
struct Vector3
{
float x, y, z; //float是四字节
};
int main()
{
int offset1 = (int)&((Vector3*)nullptr)->x;
std::cout << offset1 << std::endl; // 0
int offset2 = (int)&((Vector3*)nullptr)->y;
std::cout << offse2t << std::endl; // 4
int offset3 = (int)&((Vector3*)nullptr)->z;
std::cout << offset3 << std::endl; // 8
}
注意第11、14、17行代码逻辑,定义一个Vector3
类型的空指针,使用其分别访问成员变量x,y,z,然后取其地址并强制转化为int
型,最后进行赋值。