【问题标题】:C++ derived class is templated, base is not: how to get type from base?C++ 派生类是模板化的,基类不是:如何从基类获取类型?
【发布时间】:2016-02-23 11:44:30
【问题描述】:

我使用的是第 3 方专有软件包。它使用如下所示的数据模型:

class Base {
    ...
}

template<class T>
class Derived: public Base {
protected:
  T _t;
public:
T& getData();
}

当我与他们的代码交互时,他们会给我指向Base 对象的指针。我想写一些我自己的模板函数。我怎样才能做到这一点?即如果我知道类型 T,我可以转换它,但如果我不知道类型怎么办?我想要的是一个看起来像这样的函数:

template<T>
DataToString(Derived<T> d){
    std::stringstream ss;
    ss << d.getData();
    return ss.str();
}

可能被称为: 基数 b; std::cout

但是当我尝试这样做时,编译器告诉我它无法匹配模板。我现在得到的是每个数据类型的“猜测和检查”if/else 块,我想知道是否有更好的方法。

我认为我的问题与this 有关,但就我而言,我使用的是第 3 方库。

【问题讨论】:

  • T 类型是派生类类型的部分,因此在不知道该模板类型的情况下无法访问派生类。您需要将DataToString 实现为派生类型的一部分并使其具有多态性。

标签: c++ templates inheritance casting


【解决方案1】:

这个怎么样:

class Base {
    ...
};

class IntermediateBase : public Base {
public:
    virtual std::string toString() const = 0;
};

template<typename T>
class Derived : public IntermediateBase {
    std::string toString() const override { return "blah blah"; }
};

所以基本上你创建了一个包含虚拟toString 函数的中间基类。您知道每个 Base* 都将属于该类型,因为您的所有类型都派生自它,因此您可以强制转换为该类型并调用虚函数。

Base* basePtr = ...;
IntermediateBase* intermediateBasePtr = static_cast<IntermediateBase*>(basePtr);
std::string s = intermediateBasePtr->toString();

你也可以把你的函数写成....

std::string DataToString(Base* p) {
    return static_cast<IntermediateBase*>(p)->toString();
}

如果不是从Base 派生的每个类型都是你的,你可以dynamic_cast 来检查它是否是IntermediateBase(我强烈建议你使用更好的类名:))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-30
    • 2010-11-01
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多