c++ - 如何在 C++ 中标记要转换到哪个类?

标签 c++ types casting template-meta-programming

我正在寻找某种方法来标记我想要转换到的类(class)。我是这个网站的新手,所以请随时改进标签或其他内容。

例如,如果我有:

template<class C>
class Rotateable
{
    virtual void C Rotate() = 0;
};

class Circle : public Rotateable<Circle>
{
    Circle Rotate() { /*impl here*/ }
};

class Square : public Rotateable<Square>
{
    Square Rotate() { /*impl here*/ }
};

如果我有一个 Rotateable 的列表或数组,我如何在某处(在 Rotateable 中?)存储要尝试转换到哪个类的信息,在我可以在运行时访问的方式?

最佳答案

你不能有一个返回类型改变的虚拟。但是你可以在多态类上有类型标识符,告诉你在调用函数之前要转换到哪个类。看看这样的东西作为基本思想。 (这是 c++14 代码。如果您不使用 c++14 功能,请随意删除任何不适合您的部分。)

#include <iostream>
#include <memory>
#include <vector>

size_t generate_id()
{
    static size_t id = 0;
    return id++;
}

template <typename T>
size_t type_id()
{
    static size_t id = generate_id();
    return id;
}

class BaseRotatable
{
public:
    template <typename T>
    bool is()
    {
        return type_id<T>() == type();
    }

    virtual size_t type() = 0;
};

template <typename T>
class Rotatable : public BaseRotatable
{
public:
    size_t type() override
    {
        return type_id<T>();
    }
};

class Circle : public Rotatable<Circle>
{
public:
    Circle Rotate()
    {
        return *this; // Make this do something fancier.
    }
};

class Square : public Rotatable<Square>
{
public:
    Square Rotate()
    {
        return *this; // Make this do something fancier.
    }
};

template <typename T, typename... Args>
std::unique_ptr<BaseRotatable> factory(Args... args)
{
    T* ptr = new T(args...);
    return std::unique_ptr<BaseRotatable>{dynamic_cast<BaseRotatable*>(ptr)};
}

int main() {
    // Build a vector of rotatables.
    std::vector<std::unique_ptr<BaseRotatable>> rotatables;
    rotatables.emplace_back(factory<Circle>());
    rotatables.emplace_back(factory<Square>());

    for (auto& rotatable : rotatables)
    {
        // You can also use a switch here.
        if (rotatable->is<Circle>())
        {
            Circle& circle = *dynamic_cast<Circle*>(rotatable.get());
            auto new_circle = circle.Rotate();
            std::cout << "Type id: " << new_circle.type() << std::endl;
        }
        else if (rotatable->is<Square>())
        {
            Square& square = *dynamic_cast<Square*>(rotatable.get());
            auto new_square = square.Rotate();
            std::cout << "Type id: " << new_square.type() << std::endl;
        }
    }
    return 0;
}

关于c++ - 如何在 C++ 中标记要转换到哪个类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48577054/

相关文章:

c - 在 Linux 上用 gcc 编译的 C 代码执行转换的是什么?

c++ - 如何用 doxygen 记录一个函数对象?

c++ - 在 objective-c 项目 : c++ classes dont compile 中导入 iOS-QR-Code-Generator 文件

javascript - 如何使用特定的键子集键入对象字段的值?

java - 将对象降级为未知类

c++ - 使用boost程序选项时如何解决 "boost::bad_any_cast: failed conversion using boost::any_cast"?

c++ - 接受无限相同数量的 3 种类型的函数

c++ - 如何编写接受回调的 C 函数的 C++ 包装类方法?

java - Java中的方法不能直接返回值,为什么?

design-patterns - 设计模式 : What is a type