我想知道以下场景的优秀设计模式是什么。三个问题:
1)我有一个模板化的“Container”类,用于“Derived”的子类。我希望能够在向量中存储不同类型的模板对象(类型A或B,都是Derived的子类)。怎么做?
2)我有一个特定于模板的函数“func”,它对Containers进行操作,并且具有可变数量的参数,具体取决于Container的模板类型是A还是B.在运行时检查模板类型的好方法是什么调用适当的函数?
3)模板甚至对这个用例有意义吗?
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
struct Derived {};
struct A : Derived {
int x;
A(int x) : x(x) {}
};
struct B : Derived {
bool y;
B(bool y) : y(y) {}
};
template <typename T>
struct Container
{
T item;
Container(T i) : item(i) {}
};
// definition of a template function for type a, with specialization
void func(Container<A> c, int a, int b) {
cout << "update for A called" << endl;
}
void func(Container<B> c, bool x) {
cout << "update for B called" << endl;
}
int main(int argc, char const *argv[])
{
Container<A> * foo = new Container<A>(A(1));
Container<B> * bar = new Container<B>(B(true));
// test that func() works
func(*foo,1,2);
func(*bar,false);
vector< Container<Derived>* > vec;
// this does not work
vec.push_back(unique_ptr< Container<Derived *> >(foo));
vec.push_back(unique_ptr< Container<Derived *> >(bar));
for (Container<Derived>* d : vec) {
// how to call the proper func(d)?
}
return 0;
}
答案 0 :(得分:1)
1)您可以在A
中存储指向A *
(类型B
)或指向B *
(类型std::vector<Derived *>
)的指针,因为{{ 1}}是Derived
和A
的基础。无法将B
和Container<A>
存储到同一向量中,因为它们之间没有继承关系。这也是(间接)导致您的编译器拒绝将Container<B>
和foo
转换为bar
的原因。
2)你的func()不是&#34;模板特定功能&#34;。它甚至不是模板化的功能。它是一个重载的函数,一个变量接受两个参数,一个变量接受三个。
3)鉴于您的代码无效,无法推断您的用例是什么。鉴于您正在尝试将对象转换为不相关的类型,我的猜测是您的用例在C ++中没有意义,更不用说使用模板了。
此外,不要在C ++中使用Java(或您正在考虑的任何其他语言)技术,因为它们的工作方式不同。具体而言;
unique_ptr<Container<Derived *> >
是不必要的。它在Java中用于各种原因,即使代码编译,它们在C ++中也是无效的。相反,这样做;
Container<A> * foo = new Container<A>(A(1));
Container<B> * bar = new Container<B>(B(true));
func(*foo,1,2);
func(*bar,false);
这是有效且安全的C ++(并且不适用于Java,但这是另一个故事)。