繁体   English   中英

如何比较C ++中的类类型?

[英]How to compare class types in C++?

让我们说我有:

class Base {/*...*/}
class Derived1: public Base {/*...*/}
class Derived2: public Base {/*...*/}

..我得到了:

class SomeClass {
public:
    template<typename DerivedType>
    DerivedType GetDerived();
private:
    vector<Base*> m_classes;
}

GetDerived()函数中,我通过m_classes向量迭代,我想做类似的事情:

if(m_classes[i] == DerivedType) {
    return m_classes[i];
}

...并假设我们知道m_classes中的一个对象将包含一个'DerivedType'对象。

例:

m_classes[2] = Base* BasePtr = new Derived1;

..在这种情况下,我想像这样使用GetDerived函数:

GetDerived<Derived1>();

..这应该返回m_classes [2]

我该怎么做呢? 如何将基指针对象与派生类类型进行比较? 更确切地说, GetDerived()函数应该如何?

你可以使用dynamic_cast<>

template<typename DerivedType>
std::vector<DerivedType*> GetDerived() { // note: return type changed
 std::vector<DerivedType*> result;
 for (DerivedType* at : this->m_classes) {
  if (DerivedType* as = dynamic_cast<DerivedType*>(at)) {
   result.push_back(as);
  }
 }
 return result;
}

dynamic_cast<>需要具有运行时类型信息的Base类型(它将存在于具有虚函数的类型上)。

值得一提的是,有些人不喜欢dynamic_cast<> ,有些约定/代码库禁止它。 它是一种工具,可能会被误用。

通常做这样的事情并不是一个好主意。

如果对象不是该类型,则可以使用dynamic_cast返回nullptr否则返回指向该类型的指针:

if (nullptr != dynamic_cast<DerivedType*>(m_classes[i])) 
{ ... }

正如其他人所说,你应该看看这是否真的是解决问题的最好方法,但是在C ++中可以使用dynamic_cast 您必须使用运行时类型标识或RTTI。

一旦在编译器选项中打开它,就可以在循环中执行此操作:

DerivedType* maybeDerived = dynamic_cast<DerivedType>(m_classes[i]);
if (maybeDerived)
     return maybeDerived;

当您需要以不同方式处理不同类的对象时,将它们存储在同一个容器中是一个坏主意。

但是,这次C ++有你想要的东西。 dynamic_cast<B>(a)将尝试将a (无论是什么)转换为B类型。 如果运行时类不匹配,则返回nullptr

以下是编写GetDerived

template <class Tsearched>
Tsearched *GetDerived() {
    for(auto c : m_classes) {
        if(Tsearched *ptr = dynamic_cast<Tsearched*>(c))
            return ptr;
    }
    return nullptr;
}

或者,在标准算法的帮助下:

template <class Tsearched>
Tsearched *GetDerived() {
    auto found = std::find_if(m_classes.begin(), m_classes.end(), [](Base *ptr) {
        return dynamic_cast<Tsearched*>(ptr);
    });
    return found == m_classes.end() ? nullptr : static_cast<Tsearched*>(*found);
}

但是,让我再说一遍,这里有一个设计问题。 RTTI( dynamic_cast使用的)既不优雅也不快。

您的示例不是有效的语法。 你不能在作业中间声明。 但是,像http://en.cppreference.com/w/cpp/types/is_base_of这样的东西可以帮助识别编译时的派生。 至于在运行时识别派生类型,您可以使用dynamic_cast但理想的解决方案不应该这样做,这通常意味着您的对象或它们的使用方式存在潜在的设计缺陷。

正如@PaulMcKenzie指出的那样,你应该问自己“为什么?” 在担心如何之前。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM