当然,下面的代码给出了交叉/跳转标签初始化编译错误.但是我如何获得我想要达到的效果呢?也就是说,只实例化我真正需要的类,然后一般调用所有类共有的方法?
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)
虽然这有点令人讨厌:
#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,异常安全的变体,完美转发构造函数.只是Wrapper和main()上面不同,这里是:
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)
| 归档时间: |
|
| 查看次数: |
755 次 |
| 最近记录: |