我有当前设置:

class Interface1
{
  public:
    virtual ~Interface1() {}
    virtual void DoSomething() = 0;
};

class Interface2 : public virtual Interface1
{
  public:
    virtual ~Interface2() {}
    virtual void DoSomething() override = 0;
    virtual void DoSomethingElse() = 0;
};

class MyClass1 : public Interface1
{
  public:
    MyClass1();
    void DoSomething() override;
};

class MyClass2 : public Interface2
{
  public:
    MyClass2();
    void DoSomething() override;
    void DoSomethingElse() override;
};

int main()
{
    std::map<std::string, boost::any> items;
    items.insert(make_pair("item1", shared_ptr<Interface1>(new MyClass1())));
    items.insert(make_pair("item2", shared_ptr<Interface2>(new MyClass2())));

    auto object = items.at("item2");
    auto item = boost::any_cast<shared_ptr<Interface1>>(object);
    item->DoSomething();

    return 0;
}

当我运行此代码时,什么也没有发生。 MyClass2似乎没有调用DoSomething(),这是我想要的。我如何才能拨打Interface1::DoSomething()实际调用Interface2::DoSomething()呢?我认为这是有可能的,因为它们都相互继承,但是我似乎无法使其发挥作用。

我之所以这样想,是因为我有一些仅适用于从Interface2继承的类的函数,但是某些函数需要支持从Interface1Interface2派生的类。一旦boost::any接管了我,我松开了它原来是哪种类型,但是如果我可以使用上述设置,这应该不是问题,所以即使我的原始类是从Interface2派生的,它也可以在中调用相同的函数Interface1并获得相同的结果。

有没有一种方法可以根据当前设置进行操作?

编辑:
抱歉,构造函数前面的void不好,但这不是问题。

最佳答案

为什么需要boost::any

如果您需要确定Interface1Interface2之间的区别,并且您的 map 中存储了一个std::shared_pointer,则只需存储一个std::shared_pointer<Interface1>并使用std::dynamic_pointer_cast<Interface2>来确定您是Interface1还是Interface2
示例:

#include <map>
#include <memory>
#include <iostream>

class Interface1
{
  public:
    virtual ~Interface1() = default;
    virtual void DoSomething() = 0;
};

class Interface2 : public Interface1
{
  public:
    virtual ~Interface2() = default;
    virtual void DoSomethingElse() = 0;
};

class MyClass1 : public Interface1
{
  public:
    MyClass1() {}
    void DoSomething()     override { std::cout << "\t\t" << __PRETTY_FUNCTION__ << '\n'; }
};

class MyClass2 : public Interface2
{
  public:
    MyClass2() {}
    void DoSomething()     override { std::cout << "\t\t" << __PRETTY_FUNCTION__ << '\n'; }
    void DoSomethingElse() override { std::cout << "\t\t" << __PRETTY_FUNCTION__ << '\n'; }
};

int main()
{
    std::map<std::string, std::shared_ptr<Interface1>> items;

    items.emplace("item1", std::make_shared<MyClass1>());
    items.emplace("item2", std::make_shared<MyClass2>());

    auto check = [&items](const std::string& name)
        {
            auto object = items.at(name);
            auto item = std::dynamic_pointer_cast<Interface2>(object);
            if (item)
            {
                std::cout << name << " is an Interface2\n";
                item->DoSomething();
                item->DoSomethingElse();
            }
            else
            {
                std::cout << name << " is an Interface1\n";
                object->DoSomething();
            }
        };

    check("item1");
    check("item2");

    return 0;
}

输出:
item1 is an Interface1
        virtual void MyClass1::DoSomething()
item2 is an Interface2
        virtual void MyClass2::DoSomething()
        virtual void MyClass2::DoSomethingElse()

最后的笔记:
  • 我也质疑Interface2Interface1之间是否需要虚拟继承
  • 我不认为您需要在DoSomething中覆盖Interface2-通过公开继承Interface1已经存在
    virtual void DoSomething() override = 0;是不必要的
  • 10-05 20:48