C++如何从没有共享超类的类调用公共方法?

CXJ*_*CXJ 1 c++ c++11

当然,下面的代码给出了交叉/跳转标签初始化编译错误.但是我如何获得我想要达到的效果呢?也就是说,只实例化我真正需要的类,然后一般调用所有类共有的方法?

A类和B类实际上不在我的代码中,但在我正在使用的大型库中,因此无法更改为帮助.他们不是超类的孩子(这将解决问题).

两个实际类都处理类似的数据,因此以下面说明的方式与filter()方法兼容.我知道一些可能用于使其工作的丑陋C黑客,但我正在寻找C++惯用解决方案.

在真正的问题中,有更多的代码和更多的情况,构造函数和类方法是资源密集型的,所以我不能只是"以防万一"初始化所有可能的类,然后选择正确的filter()方法用开关().

#include <string>
#include <iostream>
class A {
public:
    std::string msg;
    A(std::string s) { msg = s;}
    void filter() { std::cout << "Message A = " << msg << std::endl;}
};

class B {
public:
    std::string msg;
    B(std::string s) { msg = s;}
    void filter() { std::cout << "The B message: " << msg << std::endl;}
};

int main() {
    int type = 1;
    switch (type) {
    case 1:
        A f("hi from A");
        break;
    case 2:
        B f("hello from B");
        break;
    }
    f.filter();
}
Run Code Online (Sandbox Code Playgroud)

编辑:根据@ stefan的回答,我修改了我的代码,看起来像下面的内容.我还没有在真实的情况下尝试过,但我相信它会奏效.(谢谢大家!)

#include <string>
#include <iostream>
class A {
public:
    std::string msg;
    A(std::string s) { msg = s;}
    void filter() { std::cout << "Message A = " << msg << std::endl;}
};

class B {
public:
    std::string msg;
    B(std::string s) { msg = s;}
    void filter() { std::cout << "The B message: " << msg << std::endl;}
};

template <class F>
void doFilterStuff(std::string msg) {
    F f(msg);
    f.filter();
}

int main() {
    for (int i=1; i<4; i++) {
        std::cout << "Type = " << i << std::endl;
        switch (i) {
        case 1:
            doFilterStuff<A>("hi from A");
            break;
        case 2:
            doFilterStuff<B>("hello from B");
            break;
        default:
            std::cout << "Throwing an error exception" << std::endl;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

moo*_*dow 5

虽然这有点令人讨厌:

#include <string>
#include <iostream>
class A {
public:
    std::string msg;
    A(std::string s) { msg = s;}
    void filter() { std::cout << "Message A = " << msg << std::endl;}
};

class B {
public:
    std::string msg;
    B(std::string s) { msg = s;}
    void filter() { std::cout << "The B message: " << msg << std::endl;}
};

// -------------

class Base
{
public:
  virtual void filter() = 0;
  virtual ~Base() {}
};

template<class C>
class Wrapper: public Base
{
public:
    Wrapper( C * impl ): m_impl(impl)   { }
    ~Wrapper()                          { delete m_impl; }

    virtual void filter()
    {
        m_impl->filter();
    }

private:
    C * m_impl;
};


// -------------

int main() {
    Base * f = NULL;

    int type = 1;
    switch (type) {
    case 1:
        f = new Wrapper<A>(new A("hi from A"));
        break;
    case 2:
        f = new Wrapper<B>(new B("hello from B"));
        break;
    }
    f->filter();
    delete f;
}
Run Code Online (Sandbox Code Playgroud)

和C++ 11,异常安全的变体,完美转发构造函数.只是Wrappermain()上面不同,这里是:

template<typename T>
class Wrapper : public Base
{
public:
    template<typename... Args>
    Wrapper(Args&&... args) : m_impl(std::forward<Args>(args)...) {}

    virtual void filter() {
        m_impl.filter();
    }

private:
    T m_impl;
};

// -------------

int main()
{
    std::unique_ptr<Base> f;

    int type = 1;
    switch (type) {
    case 1:
        f.reset(new Wrapper<A>("hi from A"));
        break;
    case 2:
        f.reset(new Wrapper<B>("hello from B"));
        break;
    }
    f->filter();
}
Run Code Online (Sandbox Code Playgroud)