【发布时间】:2019-08-28 08:43:13
【问题描述】:
目前,我们有一个包含标准组件数组的容器类。这些组件是模板化的,并且是从非模板化的基类派生的。调用成员函数时一切顺利。
但是,容器类包含模板化类型 T 的原始指针,我们希望在组件和容器类之外使用这些指针。
作为一个例子,我在这里给出了一个 std::transform,但是我们在我们的代码库和没有向量或 std 支持的 API 的许多地方使用它。
目前,我们使用原始指针,但这是非常糟糕的设计。我们使用 c++14,所有组件及其类型在编译时都是已知的。
任何想法,即我们可以用什么代替????
这是一个最小的例子:
可运行和可编辑的代码也在这里:https://rextester.com/QLP97953
#include <iostream>
#include <memory>
#include <array>
#include <algorithm>
class ComponentInterface{
public:
virtual void DoStuff() = 0;
virtual void* GetPtr() = 0;
static constexpr size_t Size() { return 10; }
};
template <class T> class Component : public ComponentInterface {
public:
Component(const std::array<T, Size()>& arr){for(int i = 0; i < Size(); ++i) ptr[i] = arr[i];}
void DoStuff() override { std::cout << ptr[0] << " " << ptr[1] << " " << ptr[2] << " " << std::endl; }
void* GetPtr() override { return (void*)(ptr); }
private:
T ptr[Size()];
};
class Container{
private:
std::array<std::unique_ptr<ComponentInterface>, 3> components;
public:
Container() {
components[0] = std::unique_ptr<Component<int> >(new Component<int>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
components[1] = std::unique_ptr<Component<float> >(new Component<float>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
components[2] = std::unique_ptr<Component<double> >(new Component<double>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}));
}
void DoStuff(int i) { components[i]->DoStuff(); }
void* GetPtr(int i) { return components[i]->GetPtr(); }
const size_t Size(int i) { return components[i]->Size(); }
};
int main()
{
Container c;
for(int i = 0; i < 3; ++i)
c.DoStuff(i);
//Works, not a good design
std::transform((int*)c.GetPtr(0), (int*)c.GetPtr(0) + c.Size(0), (int*)c.GetPtr(0), [](int a) -> int { return a + 1; });
std::transform((float*)c.GetPtr(1), (float*)c.GetPtr(1) + c.Size(1), (float*)c.GetPtr(1), [](int a) -> int { return a + 1; });
std::transform((double*)c.GetPtr(2), (double*)c.GetPtr(2) + c.Size(2), (double*)c.GetPtr(2), [](int a) -> int { return a + 1; });
for(int i = 0; i < 3; ++i)
; // ???
for(int i = 0; i < 3; ++i)
c.DoStuff(i);
}
【问题讨论】:
-
void* GetPtr() = 0;是“错误”的设计。由于所有类型都是已知的,Visitor 似乎被挪用了。 -
@Jarod42 你能用访客模式回答一下吗?