shared_ptr使用多重继承进行强制转换

时间:2018-02-15 15:28:14

标签: c++ shared-ptr multiple-inheritance

我变得有点困惑。

namespace Io
{
    class IDevice;
}

//...

namespace Sensor
{
    class IDevice;
}

//...

class ComplexDeviceHandler : public Io::IDevice, public Sensor::IDevice;

//...

std::vector<std::shared_ptr<Io::IDevice>> devices; //populated by objects of type ComplexDeviceHandler

//..

for (const auto& device : devices)
{
    std::shared_ptr<Sensor::IDevice> sensor = device; //obviously, error here
}

Io::IDeviceSensor::IDevice都是接口(有点)。 我应该使用什么演员来将std::shared_ptr<Io::IDevice>转换为std::shared_ptr<Sensor::IDevice>。在这种情况下,std::shared_ptr<Io::IDevice>存储类型为ComplexDeviceHandler的对象的地址,这是两种类型的子对象。

2 个答案:

答案 0 :(得分:3)

您需要首先尝试将其投放到ComplexDeviceHandler*,检查它是否有效,然后它可以转换为Sensor::IDevice*

for (const auto& device: devices)
{
    if (auto sidptr = std::dynamic_pointer_cast<ComplexDeviceHandler>(device)) {
        std::shared_ptr<Sensor::IDevice> sensor = sidptr;
    }
}

答案 1 :(得分:0)

这是一个基于Holt答案的编码示例,对我有用。 (非常酷,Holt!教育。)希望模仿OP用例场景。我特别使用了C ++ 17.

#include <cstddef>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

using std::cout;
using std::dynamic_pointer_cast;
using std::endl;
using std::make_shared;
using std::move;
using std::shared_ptr;
using std::string;
using std::vector;

class IFoo
{
  virtual void DoFooStuff() = 0;
protected:
  ~IFoo() = default;
public:
  void FooStuff();
};

void IFoo::FooStuff()
{
  FooStuff();
}

class IBar
{
  virtual void DoBarStuff() const = 0;
protected:
  ~IBar() = default;
public:
  void BarStuff() const;
};

void IBar::BarStuff() const
{
  DoBarStuff();
}

class Baz : public IFoo
{
  virtual void DoFooStuff() override;
public:
};

void Baz::DoFooStuff()
{
  cout << "Baz's DoFooStuff\n";
}

class Quuxplex : public IFoo, public IBar
{
  virtual void DoFooStuff() override;
  virtual void DoBarStuff() const override;
  string s;
public:
  Quuxplex(string);
  void SecretSauce() const;
};

Quuxplex::Quuxplex(string sval) : s{move(sval)}
{ }

void Quuxplex::DoFooStuff()
{
  cout << "Quuxplex's DoFooStuff with " << s << "\n";
}

void Quuxplex::DoBarStuff() const
{
  cout << "Quuxplex's DoBarStuff with " << s << "\n";
}

void Quuxplex::SecretSauce() const
{
  cout << "Quuxplex's SecretSauce with " << s << "\n";
}

int main()
{
  vector<shared_ptr<IFoo>> things;
  things.push_back(make_shared<Quuxplex>("pickle"));
  things.push_back(make_shared<Baz>());
  things.push_back(make_shared<Quuxplex>("relish"));
  things.push_back(make_shared<Baz>());
  things.push_back(make_shared<Quuxplex>("mustard"));
  vector<shared_ptr<Quuxplex>> quuxplexes;

  int found = 0;
  for (auto const& thing : things)
  {
    if (auto q = dynamic_pointer_cast<Quuxplex>(thing))
    {
      ++found;
      q->SecretSauce();
      quuxplexes.push_back(q);
      cout << "Quuxplex objects found: " << found << " count: " <<  q.use_count() << endl;
    }
  }

  return EXIT_SUCCESS;
}