我尝试了两种不同的方法来从基指针获取指向派生类的指针。第一个:
struct BaseClass {
protected:
int offset_of_derived;
public:
template <typename T>
T* getAs() { return (T*)((char*)this + offset_of_derived); }
protected:
char* getBasePtr() { return (char*)this; }
};
template <typename T>
struct DerivedClass : BaseClass
{
DerivedClass() : BaseClass() { this->offset_of_derived = (char*)this - BaseClass::getBasePtr(); }
};
我也在想我也可以这样做,我想知道这是否正确:
struct BaseClass {
private:
int offset_of_derived;
public:
template <typename T>
T* getAs() { return (T*)((char*)this + offset_of_derived); }
private:
char* getBasePtr() { return (char*)this; }
};
template <typename T>
struct DerivedClass : BaseClass
{
DerivedClass() : BaseClass() { this->offset_of_derived = (char*)this - BaseClass::getBasePtr(); }
};
也不需要 std::launder 因为我所做的只是从 char 和后面进行转换,以及从 Base - Derived 进行转换,对吗?
您似乎尝试手动实现该语言已经提供的功能。
您可以使用 2 种相关的语言结构:
dynamic_cast
。它:
沿继承层次结构向上、向下和横向安全地转换对类的指针和引用。
如果您不确定层次结构中的哪种类型是您的对象,只需使用
dynamic_cast
。如果您请求的转换无效,它将返回空指针,因此您可以随时检查自己。
如果您确定该对象实际上是派生对象,则可以使用
static_cast
(这不会产生运行时检查):
也可以使用 static_cast 执行向下转型,这样可以避免 运行时检查的成本,但只有当程序可以 保证(通过一些其他逻辑)该对象指向 表达式绝对是派生的。
请注意,如果您将
static_cast
与不是预期派生的对象一起使用,则行为未定义。