C++ C++;如果满足条件,则构造

C++ C++;如果满足条件,则构造,c++,design-patterns,constructor,C++,Design Patterns,Constructor,我有一个设计问题,其实并不复杂,但我想找到一个优雅的方法来解决它。我想到了这一点: 问题: 我有一个类a,它初始化并保存一个B的集合 B只是一个接口,必须实现(因此我们有C、D、E等类)。 在构造器中,A接收一组数据集,并且必须初始化B中的某些数据集(也包括相同或不同类的许多不同实例化)。我希望A不知道B的任何实现。 我有几个可行的解决方案,但我考虑的是一种“构造函数中的委托”。 例如: 这是因为我用来检查bi是否与初始化和性能评估应用程序中的bi完全相同的数据和演算,所以我希望避免两次这样做,

我有一个设计问题,其实并不复杂,但我想找到一个优雅的方法来解决它。我想到了这一点:

问题: 我有一个类a,它初始化并保存一个B的集合

B只是一个接口,必须实现(因此我们有C、D、E等类)。


在构造器中,A接收一组数据集,并且必须初始化B中的某些数据集(也包括相同或不同类的许多不同实例化)。我希望A不知道B的任何实现。

我有几个可行的解决方案,但我考虑的是一种“构造函数中的委托”。 例如:

这是因为我用来检查bi是否与初始化和性能评估应用程序中的bi完全相同的数据和演算,所以我希望避免两次这样做,或者在collection类中这样做。
这真的很好,但问题显然是第2行…
…以及对将异常用于实际上不是异常的事物的怀疑。(第4行)
那么,什么样的模式才是
-让我来评估数据并构建一个整体。
-避免创建几个“体系结构类”对于这样一个简单的任务,我希望避免类的爆炸(当使用以下设计模式java风格原则imho进行测试时,这是一种典型的情况)。 -尽可能快。

-…很优雅:)

答案是基于我现在的直觉,因此它可能并不完美,但另一方面,大多数设计解决方案并非如此

我会创建一个额外的类,称之为工厂或类似的东西。然后在本课程中运行所有的构造。它应该能够在运行时(通过在程序开始时运行回调)或者,更好的是,通过可变模板特征,用B的派生的可能实例化来初始化

template<class ... RegisteredBImplementations>
class CFactory
{
    B* Create (dataset const& d)
    {
        // some magical meta-ifs to create compile time conditions
        // or for (auto& registered_type : registered types), and then choose one
        return new T(d);
    }
}
模板
类工厂
{
B*创建(数据集const&d)
{
//一些神奇的meta-if可以创建编译时条件
//或(自动和注册类型:注册类型),然后选择一个
返回新的T(d);
}
}
然后,可以使用该类的实例正确初始化其指针:

for (auto& dataset : datasets)
{
    m_BPtrs.emplace_back( std::unique_ptr<dataset> (m_FactoryInstance.Create(dataset)) );
}
for(自动和数据集:数据集)
{
m_BPtrs.emplace_back(std::unique_ptr(m_FactoryInstance.Create(dataset));
}

该解决方案的要点是,类A有效地管理“B”对象,将它们的正确构造留给另一个类。它们被有效地分开,添加新的
B
实现意味着只在
c工厂
中进行更改,而不是在
a
中进行更改最简单的解决方案是委托给工厂方法

std::unique_ptr<B> build(DataSet const& ds) {
    if (ds.property() == value) {
        return std::unique_ptr<B>(new D(ds));
    }
    return std::unique_ptr<B>(new C(ds));
}
std::唯一的ptr构建(数据集常量和数据集){
if(ds.property()=值){
返回std::unique_ptr(新的D(ds));
}
返回std::unique_ptr(新的C(ds));
}

然后
A
只需要依赖于
build
的声明,您的伪代码建议了一个解决方案:您对
bi
的使用只不过是一个工厂函数,它将
数据集
作为输入,并将
B*
作为输出。因此,您实际上只需要从
std::function
对象的集合中获取
bi


要求这些工厂只是“条件”工厂是很容易的:有时它们返回有效对象,有时不返回,而是返回
nullptr
。这将使您避免异常,并且更忠实于您的使用意图。

“我希望A不知道B的任何实现。”-然后您不能迭代实现。基本上,您希望构造函数上的多态性。。。?!?但您收到的数据类型是什么<代码>无效*?+1表示Java设计模式中的“类爆炸”@巴特克:我不需要迭代实现。A只是一个向量。对于多态性,我做我想做的。@DevSolar:数据类型是统一的(点/边/形状的集合)(它是一个人工智能/机器人应用程序,数据集是一组半处理的感觉(激光、相机等)),这是一个迈向更高级别感知的类。这是我不想做的,但从一开始就似乎不可避免。如果没有其他想法,我最终会这么做。
std::unique_ptr<B> build(DataSet const& ds) {
    if (ds.property() == value) {
        return std::unique_ptr<B>(new D(ds));
    }
    return std::unique_ptr<B>(new C(ds));
}