YouTube视频链接
C++的箭头操作符
本文是ChernoP45视频的学习笔记。
如下代码,当拥有一个指针ptr的时候,为了调用Print函数不能用.Print。
#include<iostream>
#include<string>
class Entity
{
public:
int x;
public:
void Print() const { std::cout << "Hello" << std::endl; }
};
int main()
{
Entity e;
e.Print();
Entity* ptr = &e;
ptr.Print();//报错
std::cin.get();
}
因为这只是一个指针,也就是一个数值而不是对象所以不能调用方法。实际上需要逆向引用(*ptr),用ptr前面的星号来逆向引用它,然后用entity替换。
Entity* ptr = &e;
Entity& entity = *ptr;
entity.Print();
或者简化一行,用圆括号括起来然后逆向引用。
Entity* ptr = &e;
(*ptr).Print();
还可以使用箭头操作符,而不是逆向引用指针然后调用Print。
Entity* ptr = &e;
ptr->Print();
ptr->x=2;
C++可以重载箭头操作符,并在自己定义的类中使用它。假设写一个智能指针的类叫ScopedPtr,当Entity超出范围时类会自动删除。
#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;
}
Entity* GetObject() { return m_Obj; }
};
int main()
{
ScopedPtr entity = new Entity();
entity.GetObject()->Print();
std::cin.get();
}
若希望能够像使用堆分配的Entity一样使用它。
Entity* entity = new Entity();
entity->Print();
若想把它用同样的方法替代,就需要重载箭头操作符。
#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;
}
Entity* operator->() //重载
{
return m_Obj;
}
};
int main()
{
ScopedPtr entity = new Entity();
entity->Print();
std::cin.get();
}
若是const ScopedPtr entity = new Entity();,返回一个const Entity,并标记此运算符重载为const,注意Print函数也要标记为const。
#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()
{
const ScopedPtr entity = new Entity();
entity->Print();
std::cin.get();
}
还可以使用箭头操作符来获取内存中某个成员变量的偏移量。假设有一个Vector3结构体有三个浮点数分量xyz,若想要找出这个变量在内存中的偏移量,例如x偏移量是0,y是4,z是8。
#include<iostream>
#include<string>
struct Vector3
{
float x, y, z;
};
int main()
{
int offse_x = (int)&((Vector3*)0)->x;
//int offse_x = (int)&((Vector3*)nullptr)->x;
int offse_y = (int)&((Vector3*)0)->y;
//int offse_y = (int)&((Vector3*)nullptr)->y;
int offse_z = (int)&((Vector3*)0)->z;
//int offse_z = (int)&((Vector3*)nullptr)->z;
std::cout << offse_x << std::endl;
std::cout << offse_y << std::endl;
std::cout << offse_z << std::endl;
std::cin.get();
}