【问题标题】:How do I cast a templated class如何转换模板类
【发布时间】:2020-07-08 16:42:27
【问题描述】:

我有一个类似下面的 C++ 示例,我收到一个指向基类 exampleParent 的指针,并希望将其转换为指向继承类 example 的指针(实际上我只是想调用example) 上的一个函数。需要注意的是继承的类是模板化的。在下面的示例中,我知道模板的类型为int,所以没有问题。一般来说,如果我事先不知道模板的类型,有什么好的方法可以做到这一点?

class exampleParent{};

template<typename P>
class example: public exampleParent
{
public:
    int do_something() const
    { 
        std::cout<<"I am doing something"<<std::endl;
        return 0;
    }
};

boost::shared_ptr<const exampleParent> getPtr()
{
   return boost::make_shared<const example<int>>();
}

int main()
{
    boost::shared_ptr<const exampleParent> example = getPtr();
    auto example_ptr = boost::dynamic_pointer_cast<const example<int>>(example);
    return example_ptr-> do_something();
}

我建议的一个解决方案是将代码更改为以下内容:

class exampleParent{};
class something_interface: public exampleParent
{
public:
    virtual int do_something() const = 0 ;
};

template<typename P>
class example: public something_interface
{
public:
    int do_something() const override
    { 
        std::cout<<"I am doing something"<<std::end;
        return 0;
    }
};

boost::shared_ptr<const exampleParent> getPtr()
{
   return boost::make_shared<const example<int>>();
}

int main()
{
    boost::shared_ptr<const exampleParent> example = getPtr();
    auto example_ptr = boost::dynamic_cast<const something_interface>(example);
    return example_ptr->do_something();
}

这行得通,但感觉有点骇人听闻:something_interface 不应该真的存在,因为它本身没有面向对象的解释。

任何帮助将不胜感激!

【问题讨论】:

  • 这实际上是 C++ 中一个非常标准的概念:接口除了为其他人添加他们的实现创建入口点之外什么都不做。

标签: c++ templates inheritance casting


【解决方案1】:

如果您可以将exampleParent 设为抽象类(如果您可以修改该类),那将是最好的:

class exampleParent
{
public:
    virtual ~exampleParent() = default;
    virtual int do_something() const = 0; 
};
template<typename P>
class example: public exampleParent
{
public:
    int do_something() const override
    { 
        std::cout<<"I am doing something"<<std::endl;
        return 0;
    }
};

那么您不需要强制转换来调用该方法。

如果你无法触及这个exampleParent 类,请按照你的建议继续使用中间类,但请记住实际继承exampleParent 并且不要抛出异常,只需将方法设为纯虚拟即可:

class intermediate: public exampleParent
{
public:
    ~intermediate() override = default;
    virtual int do_something() const = 0;
};

否则唯一的方法是对所有可能的类型执行dynamic_pointer_cast 并检查转换结果,因为模板类的不同实例通常只是不同的类型。当然,如果有无数个可能的模板参数P,那是没有意义的。

【讨论】:

  • 谢谢,我不能修改 exampleParent,所以我会遵循第二个建议
猜你喜欢
  • 1970-01-01
  • 2023-04-01
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 2016-10-21
  • 2017-01-13
  • 2020-06-07
  • 2015-06-27
相关资源
最近更新 更多