c++ - 如何返回子类的真实 self 类型?

标签 c++

我想要一个函数返回它的真实类型,即使它在子类中调用。这是测试代码:

class Super
{
public:
    Super(){};
    virtual auto getSelf() -> decltype(*this)&
    {
        return *this;
    }
    void testSuper(){};
};

class Sub : public Super
{
public:
    void testSub(){};
};

int main() 
{
    Sub().getSelf().testSuper();//OK
    //Sub().getSelf().testSub();//Error
    return 0;
}

在 Objective-C 中,我可以使用 instanttype 来解决这个问题。
但是在 C++ 中,这可能吗?

顺便说一句,我不想​​要模板实现,因为它可能会增加代码大小。

最佳答案

But in C++, is it possible?

是的,就像 C++ 中的任何东西一样,有很多方法可以做到这一点。但是这两种方法都需要您在 Sub 类中添加一些内容。

如果您不需要虚函数,则只需(静态地)覆盖该函数:

struct Super {
    auto getSelf() -> Super& {
        return *this;
    }

    void testSuper(){};
};

struct Sub : Super {
    auto getSelf() -> Sub& {
        return *this;
    }

    void testSub(){};
};

int main() {
    Sub().getSelf().testSuper(); //OK
    Sub().getSelf().testSub(); //OK too!
    return 0;
}

当然,如果您不喜欢复制粘贴该代码,您可以随时创建一个混合类(CRTP 模板):

template<typename Subclass>
struct AddGetSelf {
    auto getSelf() -> Subclass& {
        return static_cast<Subclass&>(*this);
    }
};

你可以像这样在你的类中使用那个mixin:

struct Super : AddGetSelf<Super> {
    using AddGetSelf<Super>::getSelf;

    void testSuper(){};
};

struct Sub : Super, AddGetSelf<Sub> {
    using AddGetSelf<Sub>::getSelf;

    void testSub(){};
};

如果你需要虚拟多态性,你可以依赖协变返回类型:

struct Super {
    virtual auto getSelf() -> Super& {
        return *this;
    }

    void testSuper(){};
};

struct Sub : Super {
    auto getSelf() -> Sub& override {
        return *this;
    }

    void testSub(){};
};

int main() {
    Sub().getSelf().testSuper(); //OK
    Sub().getSelf().testSub(); //OK too!
    return 0;
}

这是Coliru 上的一个实例

如果您担心二进制大小,请考虑静态链接和链接时间优化。

我建议您尝试这两种解决方案并比较二进制大小,因为模板大小的增加可以通过编译器优化来抵消,而虚拟多态性可以阻止编译器进行这些优化。

关于c++ - 如何返回子类的真实 self 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41582576/

相关文章:

c++ - 类派生形式结构上的虚函数

c++ - 在图像扫描上下文中了解嵌套数组C++

c++ - 如何在 C++ 中通过命令行参数传递常量 int?

c++ - 引用变量

c++ - 管道和套接字有什么区别?

c++ - 使用 Microsoft Access 数据库在 C++ 中进行 Unicode 转换

c++ - C++17中类模板的模板参数推导 : am I doing it wrong?

c++ - c/c++ 中的 url 缩短算法 - 面试

c++ - Windows:是否有我可以作为 Visual C++ 资源引用的内置加载动画?

c++ - sqlite:检查读写器锁