- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个模板化容器 World
,它包含 Object
。 World
是在 Object
上执行的工作流。
通常我使用默认构造函数构造 Object
,但现在我需要从运行时提供一些参数。
我的问题是找到一种好的、干净的方法来使 World
使用给定值初始化 Object
。
建议方案一
现在我已经在 main.cpp
中创建了一种 Init
对象,它保存了 Object
初始化所需的值我设置它并在 Object
的构造函数中将它传递给 Init
的实例以执行初始化。它看起来像这样:
对象.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。这是一个好的解决方案吗,它有名称吗(可能是设计模式或反模式)?
建议方案二
我在想,我可以通过一些 World::init_objects
方法传递构造 Object
所需的参数。我相信这是可能的,因为 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。这种方法是否可行,或者有什么重大缺点? (我想我更喜欢它,但也许很快就会碰壁是个坏主意。)
第 3 季度。有没有更好的方法来做到这一点,我没有想到。也许这是一个简单的问题,需要一个设计模式/实现。
我认为我提出的解决方案并不相互排斥,但我想清理我凌乱的代码,并选择一个好的、干净的、好的代码实践来拾起并坚持下去。
最佳答案
Q1. Is this a good solution, and does this have a name (perhaps it's a design pattern, or antipattern)?
是的。这(或多或少)是工厂对象模式(尽管在工厂对象实现的典型示例中,对象并不“知道”工厂是什么——对象中没有对工厂的静态引用)。
Q2. Is such approach feasible, or has any major drawbacks? (I think I like it better, but maybe it is a bad idea that will hit a wall soon.)
解决方案是可行的。一个缺点是您在要在对象中设置的参数/值上实现模板的方式。
改为考虑这个实现:
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
(您可以注入(inject)初始化或其他任何东西)。
作为旁注,还可以考虑使用工厂函数(针对世界,而不是内部对象)基于已构建的对象 vector 创建世界对象。这将消除对对象进行额外初始化的需要(即它不会影响世界的公共(public)接口(interface))并将世界变成一个异常安全的对象(它可能仍然需要上面的 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)};
}
关于c++ - 初始化容器中对象的正确方法/模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21829976/
我是 Spring 新手,这就是我想要做的事情: 我正在使用一个基于 Maven 的库,它有自己的 Spring 上下文和 Autowiring 字段。 它的bean配置文件是src/test/res
我在我的测试脚本中有以下列表初始化: newSequenceCore=["ls", "ns", "*", "cm", "*", "ov", "ov", "ov", "ov", "kd"] (代表要在控
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Class construction with initial values 当我查看 http://en.
我得到了成员变量“objectCount”的限定错误。编译器还返回“ISO C++ 禁止非常量静态成员的类内初始化”。这是主类: #include #include "Tree.h" using n
我有如下所示的a.h class A { public: void doSomething()=0; }; 然后我有如下所示的b.h #include "a.h" class b: publi
我需要解析 Firebase DataSnapshot (一个 JSON 对象)转换成一个数据类,其属性包括 enum 和 list。所以我更喜欢通过传递 DataSnapshot 来手动解析它进入二
我使用 JQuery 一段时间了,我总是使用以下代码来初始化我的 javascript: $(document).ready( function() { // Initalisation logic
这里是 Objective-C 菜鸟。 为什么会这样: NSString *myString = [NSString alloc]; [myString initWithFormat:@"%f", s
我无法让核心数据支持的 NSArrayController 在我的代码中正常工作。下面是我的代码: pageArrayController = [[NSArrayController alloc] i
我对这一切都很陌生,并且无法将其安装到我的后端代码中。它去哪里?在我的页脚下面有我所有的 JS? 比如,这是什么意思: Popup initialization code should be exec
这可能是一个简单的问题,但是嘿,我是初学者。 所以我创建了一个程序来计算一些东西,它目前正在控制台中运行。我决定向其中添加一个用户界面,因此我使用 NetBeans IDE 中的内置功能创建了一个 J
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
据我所知, dependentObservable 在声明时会进行计算。但如果某些值尚不存在怎么办? 例如: var viewModel ={}; var dependentObservable1 =
我正在阅读 POODR 这本书,它使用旧语法进行默认值初始化。我想用新语法实现相同的功能。 class Gear attr_reader :chainring, :cog, :wheel de
我按照 polymer 教程的说明进行操作: https://www.polymer-project.org/3.0/start/install-3-0 (我跳过了可选部分) 但是,在我执行命令“po
很抱歉问到一个非常新手的Kotlin问题,但是我正在努力理解与构造函数和初始化有关的一些东西。 我有这个类和构造函数: class TestCaseBuilder constructor(
假设我们有一个包含 30 列和 30 行的网格。 生命游戏规则简而言之: 一个小区有八个相邻小区 当一个细胞拥有三个存活的相邻细胞时,该细胞就会存活 如果一个细胞恰好有两个或三个活的相邻细胞,那么它就
我是 MQTT 和 Android 开放附件“AOA” 的新手。在阅读教程时,我意识到,在尝试写入 ByteArrayOutputStream 类型的变量之前,应该写入 0 或 0x00首先到该变量。
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
我有一个inotify /内核问题。我正在使用“inotify” Python项目进行观察,但是,我的问题仍然是固有的关于inotify内核实现的核心。 Python inotify项目处理递归ino
我是一名优秀的程序员,十分优秀!