【问题标题】:Identifying which Base Class shared_ptr has been passed into a Super Class shared_ptr vector识别已将哪个基类 shared_ptr 传递到超类 shared_ptr 向量中
【发布时间】:2012-12-02 19:27:55
【问题描述】:

我正在开发一个 C++ 项目,专门实现一个调车场算法。

我有一个函数可以创建一个超类shared_ptr 的向量,但是被推入这个向量的类都是基类shared_ptrs。

然后我需要获取这个向量并将其传递给另一个函数,并在 for 循环中对向量的每个元素执行不同的逻辑。然而,我执行的逻辑取决于向量的每个元素中存在哪个基类。

所以基本上我不知道的是如何识别向量的每个元素中的基类类型。当我调试它们时,它们都以类型超类的形式出现。

所以通常我想做这样的事情:

if(vectorElement == baseClass)
{
  //do some logic
}

或者,如果有一些我想念的不同方法来执行此操作,我会有兴趣执行此操作。

【问题讨论】:

  • 我不能说我 100% 了解你,但你也许正在寻找 dynamic_castdynamic_pointer_cast
  • 这两个术语基类和超类代表一个类派生自。派生类也称为子类(细微差别:-))。所以请编辑您的帖子以明确
  • 可能有一种方法可以在我的解决方案中实现这一点,但我认为我能想到的任何方法都不可行。
  • 我认为我确实需要使用 dynamic_pointer_cast,但我对其工作原理的理解并不清楚。如果有人能解释清楚,将不胜感激。

标签: c++ inheritance vector shared-ptr


【解决方案1】:

您的问题有很多解决方案,坦率地说,这是 OOP 中几乎最常见的问题。

最明显的是虚函数在不同的类中做不同的事情:

class SuperClass {
public:
   virtual void doSomething(/*someArgsIfNeeded*/) {
      // some base implementation, possible empty
      // or just use pure virtual function here
   }
};

class SubClass : public SuperClass {
public:
   virtual void doSomething(/*someArgsIfNeeded*/) {
      // some base implementation
   }
};

然后按如下方式使用:

int SomeArgs;
std::vector<std::shared_ptr<SuperClass>> objects;
for (auto it = objects.begin(); it != objects.end(); ++i)
  it->doSomething(/*someArgsIfNeeded*/);

其他更复杂的解决方案是使用visitor pattern


使用强制转换 (dynamic_cast) 被认为是一种不好的做法,因此始终寻找比强制转换更多的 OO 解决方案,就像我上面介绍的这两个。

【讨论】:

  • 我不确定这个解决方案是否能解决我的问题。我知道我可以从向量中调用特定于基类的函数,但是我需要在不使用函数调用的情况下识别基类是哪个类。我实际上并没有从基类调用任何函数,也无法修改这些类。
  • @danner 澄清(提供代码或其他东西)这个描述“我有一个函数可以创建一个超类类型的 shared_ptr 向量,但是被推入这个向量的类都是基类 shared_ptrs . "...
  • @danner 我的意思是哪些代码是你的,你可以修改,哪些不是你的,你不能修改......
【解决方案2】:

在我的脑海中,一个简单的解决方案是在基类中有一个函数,它返回一个表示它是哪个类的 int。并且在每个派生类中,重写此函数以返回不同的值。您可以使用该值来确定将哪个类存储在向量中

编辑:通常类特定的细节将留在类中,这是多态性的重点。尝试将派生类特定的计算作为每个类中的覆盖成员函数进行,并使用它来获取值,而不需要在外部进行大型 for 循环(对于每个新的派生类)。

【讨论】:

  • 通常做这样的自制类型 ID 是个坏主意。 dynamic_cast 就是针对这个问题发明的
  • 是的,这行得通。我唯一的问题是我正在使用其他人的代码,并且我无法自己修改类。如果一切都失败了,我可以尝试这个解决方案,但是如果有一种方法可以在不修改首选类的情况下做到这一点。每个类中都有一个名为“is_convertable_from”的函数,它返回一个布尔值,具体取决于该类是否可以从基类转换。但我不完全确定它是如何工作的。
  • */#define DEF_IS_CONVERTABLE_FROM(type)\ public: virtual bool is_convertable_from( Token::pointer_type const& ptr ) const {\ return dynamic_cast( ptr.get() ) != 0 ;\ } 这就是那个函数。 .
  • 所以事实证明我确实需要使用 static_dynamic_casting 来解决这个问题。使用 SDC,您可以将对象向下转换到层次结构的任何位置,并且仅当对象是层次结构的一部分时,转换才会起作用。因此,如果我将乘法对象转换为乘法对象,我可以使用 if 语句表示 If(multiplicationObject != 0) 或层次结构为 Operator->Multiplication 的运算符对象,我可以使用 if 语句表示 If(Operator != 0)。但是任何不属于层次结构的东西都会返回 0 或空,并且会在 if 中返回 false。
猜你喜欢
  • 1970-01-01
  • 2013-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-16
  • 2012-11-04
  • 1970-01-01
相关资源
最近更新 更多