C++中的类型转换和继承

Typecasting and inheritance in C++

本文关键字:继承 类型转换 C++      更新时间:2023-10-16

我有个问题。有两类:

struct Base {
    Base* retain() {
    //retain here
        return this;
    }
};
struct Derived : Base {
};

Derived *d1 = new Derived();
Derived *d2 = d1->retain(); //error here: need to typecast to Derived*
Derived *d3 = (Derived*)d1->retain(); //OK

有没有什么方法可以重写retain()函数,使其不需要手动对结果进行类型转换?换句话说:retain()应该返回派生类型的对象。

template<typename T>
struct Base
{
    T* retain()
    {
        return (T*)this;
    }
};
struct Derived : Base<Derived>
{
};

Derived *d1 = new Derived();
Derived *d2 = d1->retain();

或者:

struct Base
{
    template<typename T>
    void retain(T** ptr)
    {
        *ptr = (T*)this;
    }
};
struct Derived : Base
{
};
Derived *d1 = new Derived;
Derived *d2;
d1->retain(&d2);

通常,当你做你正在做的事情时,基类会有一个虚拟析构函数。这允许运行时类型标识。

您可能还想编写struct Derived : public Base,包括关键字public

关于虚拟析构函数的解释如下。

一个简单类的对象,即缺乏虚拟方法的类,只不过是内存中的数据集合。具有此类对象地址的代码无法仅通过查看对象来判断该对象是基类型还是派生类型。

但是,如果基类型至少有一个虚拟方法,则编译器会向该类型的每个对象添加一个隐藏指针。该指针指向一个表,该表准确地标识了对象的类型,从而使指针上的dynamic_cast<>()和其他多态操作成为可能。

如果所有这些对您来说都是新的,那么我建议您下一步尝试:向基类添加一个空的虚拟析构函数virtual ~Base() {},然后阅读关于dynamic_cast<>()的内容。接下来,您可能希望使基本retain()也是虚拟的,然后赋予Derived它自己的,覆盖retain()

无论如何,除非你能得到更有针对性的建议,否则前面的内容应该会给你一些开始的东西。祝你好运