初始化容器中对象的正确方法/模式

luk32

我有一个模板容器World,其中包含Objects。World是在上执行的工作流程Object

通常,我Object使用默认构造函数构造,但是现在我需要在运行时提供一些参数。

我的问题是找到一种很好的方法来使带有给定值的Worldinitializes Object

拟议解决方案1

目前,我已经创建了一种Init对象,该对象包含初始化所需的值,该对象Objectmain.cppI中进行了设置,并在ObjectI的构造函数中将其传递给的实例Init以执行初始化。看起来像这样:

Object.h:

class Object; //forward declaration
struct Init {
  void Initialize(Object& object);
  int property1;
  double property2;
  string property3;
};

class Object{
 static Init init;
public:
 Object(){
   init.Initialize(*this);
 }
};

这种方式World不需要对的构造有任何了解,Object而可以使用默认的构造函数。

我不喜欢这种解决方案过于复杂,因此我正在寻找更好的解决方案。

Q1这是一个好的解决方案,它是否有名称(也许是设计模式或反模式)?

拟议解决方案2

我当时以为我可以Object通过某种World::init_objects方法传递构造一个所需的参数我相信自c ++ 11起这是可能的。init_objects方法可以是构造对象的可变参数模板。

建议的示例:

template<typename Object>
class World {
  std::vector<Object> _internal_container;
  size_t _size;
public:
  World(size_t size) : _size(size) { _internal_container.reserve(_size); };

  template<typename... Args>
  init_objects(const Args&... args){
    for(size_t i = 0; i < _size; ++i) _internal_container.emplace_back( Object(args) );
  }
}

这样,我没有多余的对象,World也不需要了解任何Object内部结构。main.cpp需要调用init_objects而不是设置Object::init实例。

Q2这样的方法是否可行,或有什么主要缺点?(我认为我更喜欢它,但是也许这是一个坏主意,很快就会碰壁。)

Q3有没有想到的更好的方法呢?可能是设计模式/实现的一个简单问题。

我认为我提出的解决方案不是相互排斥的,但是我想清理我的混乱代码,并选择一个好的,干净且不错的代码实践来坚持下去。

乌地那汀

Q1。这是一个好的解决方案,它是否有名称(也许是设计模式或反模式)?

是。这(或多或少)是工厂对象模式(尽管在工厂对象实现的规范示例中,对象并不“知道”工厂是什么-对象中没有对工厂的静态引用)。

Q2。这样的方法是否可行,或有什么主要缺点?(我认为我更喜欢它,但是也许这是一个坏主意,很快就会碰壁。)

该解决方案是可行的。缺点之一是对要在对象中设置的参数/值实施模板的方式。

请考虑以下实现:

template<typename Object>
class World {
    std::vector<Object> objects;
    // size_t _size; // << size removed
public:
    World(size_t size) : objects(size) // use default constructor 
    {}

    template<typename P> // << changed here
    void apply(P predicate) { // << change here
        std::for_each(objects.begin(), objects.end(), predicate); // << and here
    }
};

客户代码:

World w{10}; // create 10 objects with default values
w.apply([](object& o) { o.set_xyz(10); o.set_yyy(20); });

使用此解决方案,您可以apply以模块化的方式使用(可以注入初始化或其他方法)。

作为附带说明,还可以考虑使用工厂函数(针对World,而不针对内部对象)基于已经构造的对象矢量创建World对象。这将消除对对象的额外初始化的需要(即,不会影响世界的公共接口),并将World变成异常安全对象(apply出于其他目的,它仍可能需要上述方法):

template<typename O> class World {
    std::vector<O> objects;
public:
    World(std::vector<O> obj) : objects{std::move(obj)} {}
    // eventually define apply function here
};

template<typename O, typename... Args>
World<O> make_world(size_t size, const Args&... args){
    std::vector<O> objects{size};
    for(auto& o: objects)
    { /* set arguments here */ }
    return World<O>{std::move(objects)};
}

编辑:具体的make_world示例,而不要求封装对象的默认构造函数:

struct Length { int length; Length(int l) : length{l} {} };

World<Length> make_length_world(size_t size, int default_length)
{
    std::vector<Length> values;
    for(size_t index = 0; index < size; ++index)
        values.emplace_back(default_length);
    return World<Length>{std::move(values)};
}

struct Person {
    std::string first_name; std::string last_name;
    Person(std::string first, std::string last)
    : first_name{std::move(first)}, last_name{std::move(last)} {}
};


World<Person> make_robert_paulson_world(size_t size)
    // "his name is Robert Paulson"
    // so don't pass name as parameter
{
    std::vector<Person> values;
    for(size_t index = 0; index < size; ++index)
        values.emplace_back("Robert", "Paulson");
    return World<Person>{std::move(values)};
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在JS对象中初始化此属性的正确方法

来自分类Dev

在python中更改初始化对象的正确方法

来自分类Dev

猫鼬-初始化嵌套模式的正确方法

来自分类Dev

在React容器中哪里初始化Socket对象?

来自分类Dev

在Android中实例化和初始化对象的正确方法

来自分类Dev

Kotlin对象。哪种初始化方法是正确的?

来自分类Dev

在Swift中初始化NSWindowController对象的正确方法是什么?

来自分类Dev

如何正确初始化C ++中的对象向量?

来自分类Dev

在C ++对象中初始化数据成员的正确顺序

来自分类Dev

在Swift 1.1中覆盖初始化程序的正确方法

来自分类Dev

在Python中初始化全局变量的正确方法

来自分类Dev

在HTML中初始化变量的正确方法

来自分类Dev

在方法中初始化后如何正确显示JFrame

来自分类Dev

在C ++中初始化结构内数组的正确方法

来自分类Dev

正确的方法在骨架.js中初始化jquery库

来自分类Dev

如何在 Karaf 中的容器初始化期间记录由 Blueprint (Aries) 创建的对象的初始化?

来自分类Dev

用不同的值初始化const容器的正确方法是什么?

来自分类Dev

在方法中初始化对象-MQL5

来自分类Dev

在Objective-C中初始化对象的最佳方法

来自分类Dev

对象在方法中初始化后为空

来自分类Dev

正确的数据初始化方法

来自分类Dev

正确的Rails初始化方法调用

来自分类Dev

处理失败初始化的正确方法

来自分类Dev

用移动廉价但要复制的对象初始化容器的首选方法是什么

来自分类Dev

Java:在初始化块中初始化对象时从另一个类调用对象的方法

来自分类Dev

初始化Gson对象的最佳方法

来自分类Dev

初始化对象时调用方法

来自分类Dev

在@Shared或setupSpec()中初始化对象

来自分类Dev

未在Ruby中初始化的对象

Related 相关文章

  1. 1

    在JS对象中初始化此属性的正确方法

  2. 2

    在python中更改初始化对象的正确方法

  3. 3

    猫鼬-初始化嵌套模式的正确方法

  4. 4

    在React容器中哪里初始化Socket对象?

  5. 5

    在Android中实例化和初始化对象的正确方法

  6. 6

    Kotlin对象。哪种初始化方法是正确的?

  7. 7

    在Swift中初始化NSWindowController对象的正确方法是什么?

  8. 8

    如何正确初始化C ++中的对象向量?

  9. 9

    在C ++对象中初始化数据成员的正确顺序

  10. 10

    在Swift 1.1中覆盖初始化程序的正确方法

  11. 11

    在Python中初始化全局变量的正确方法

  12. 12

    在HTML中初始化变量的正确方法

  13. 13

    在方法中初始化后如何正确显示JFrame

  14. 14

    在C ++中初始化结构内数组的正确方法

  15. 15

    正确的方法在骨架.js中初始化jquery库

  16. 16

    如何在 Karaf 中的容器初始化期间记录由 Blueprint (Aries) 创建的对象的初始化?

  17. 17

    用不同的值初始化const容器的正确方法是什么?

  18. 18

    在方法中初始化对象-MQL5

  19. 19

    在Objective-C中初始化对象的最佳方法

  20. 20

    对象在方法中初始化后为空

  21. 21

    正确的数据初始化方法

  22. 22

    正确的Rails初始化方法调用

  23. 23

    处理失败初始化的正确方法

  24. 24

    用移动廉价但要复制的对象初始化容器的首选方法是什么

  25. 25

    Java:在初始化块中初始化对象时从另一个类调用对象的方法

  26. 26

    初始化Gson对象的最佳方法

  27. 27

    初始化对象时调用方法

  28. 28

    在@Shared或setupSpec()中初始化对象

  29. 29

    未在Ruby中初始化的对象

热门标签

归档