C++ 处理可以';你不能实例化自己吗?
我想我以前也问过一些类似的问题,但我是绕圈子的。我想这才是真正的问题,我不能完全放心 我处理的是一个,有一个对象无法创建自己,C++ 处理可以';你不能实例化自己吗?,c++,design-patterns,qt,box2d,C++,Design Patterns,Qt,Box2d,我想我以前也问过一些类似的问题,但我是绕圈子的。我想这才是真正的问题,我不能完全放心 我处理的是一个,有一个对象无法创建自己,b2Body。b2World的。我个人不太喜欢这种设计模式;我认为,b2Body应该能够独立于世界而存在,然后在需要时添加到世界中。无论如何,我已经用我自己的类,Body包装了b2Body,因为我需要向它添加一些额外的东西。类似地,我有一个World包装器。现在我想我有3个选择: HaveBody的构造函数获取指向World的指针,这样它就可以被完全实例化(调用b2Wor
b2Body
。b2World的。我个人不太喜欢这种设计模式;我认为,b2Body
应该能够独立于世界而存在,然后在需要时添加到世界中。无论如何,我已经用我自己的类,Body
包装了b2Body
,因为我需要向它添加一些额外的东西。类似地,我有一个World
包装器。现在我想我有3个选择:
HaveBody
的构造函数获取指向World
的指针,这样它就可以被完全实例化(调用b2World::CreateBody
内部的某个地方)——也就是说,有一个像Body*b=newbody(World_ptr)
将Body
传递给一些World::CreateBody
方法,就像库已经做过的那样——即Body*b=World.CreateBody(params)代码>
复制b2Body
中的所有数据,以便您可以随意使用它,然后在您将其添加到世界后,它将“切换”到使用b2Body
数据,即Body b
和以后的world.addBody(b)
(1) (2)意味着如果没有一个世界,你就不能拥有主体
,我可能不需要它,但拥有这个选项可能会更好[这样我就可以将它用作其他对象等的模板]。不知道还有什么其他的优点和缺点。(3) 看起来更好,但要实现它需要做更多的工作,这意味着我必须复制b2Body
中已经包含的大部分数据
你的想法是什么?我将CW
这样就不会有人担心了
我还是不能就此罢休。这是每个选项的外观:
选项1:(我更喜欢)
选项2:(中间的某个地方)
选项3:(Box2D是如何实现的)
选项2和3没有什么不同,但它改变了谁可以控制对象的创建
但是,我将如何实际实施选项3World::CreateBody()
必须调用b2World::CreateBody(args)
它调用b2Body::b2Body()
并返回b2Body
,但从不调用Body::Body(args)
,这是一个问题。b2Body
将被完全初始化,但我的包装器没有地方做它的事情。。。更具体地说,我将如何编写World::CreateBody(constbodydef&bd)
?假设BodyDef继承自b2BodyDef、b2Body继承自b2Body、b2World继承自b2World等等。听起来b2World对象是b2Body的工厂,因此作者认为b2Body没有世界就没有意义
我的第一反应是,这是接口,所以请接受它。让你的世界对象成为你身体的工厂。这接近方法(1),除了没有公共构造函数外,世界对象有一个makeBody()方法
你认为没有世界的身体有意义吗?如果是这样的话,也许你会发现身体方法的某些子集在没有世界的情况下是有用的,我不清楚你是如何实现它们的——它们显然不能由b2Body实现,因为没有b2Body他就不可能存在。因此,一种可能性是您有一组配置信息
class Body {
int howBig;
String name;
Flavour flavour;
// and getter/setters
}
现在这些(或在东方的bgetters)显然在有或没有世界的情况下都是有意义的
考虑到这一点,我想你们可能会发现,你们的身体实际上有两种“状态”,一种是和世界无关的状态,另一种是和世界相关的状态。而实际能力是不同的。因此,实际上有两个接口
所以有一个独立的Body类和一个Body类。世界工厂方法可能有一个签名
World {
Body makeBody(IndependentBody);
}
我认为,如果你打算使用第三方库,你应该只有在你有更好的理由的情况下才反对它的设计,而不是哦,我不太喜欢那种设计模式。您的库有一种处理事情的方式—显然,通过使用工厂对象—并与之抗争,这将增加您的代码复杂性,可能会大大增加。我同意您不应该与正在使用的第三方库的设计抗争。沿着这条路走下去会在未来造成很多问题
通过查看“隐藏”和创建包装,您可能将第三方库的行为锁定为当前实现的行为方式
如果API的未来版本保持不变,但底层语义发生变化,会发生什么情况
突然间,从包装纸的角度来看,一切都被打破了
仅我的0.02。在您的链接之后,我看到createBody
不返回b2Body,而是指向b2Body的指针:
这很可能是因为这个世界
管理b2Body生存期(即,当B2World超出范围/自身被删除时,删除它和它使用的内存),或
因为B2WSWorld需要维护指向B2Body的指针,例如,对它们进行迭代以实现某些B2World功能
我还注意到创建b2Body
所需的全部(除了b2World
)是指向b2BodyDef
的指针
所以,如果你想要一个b2Body,它没有连接到一个b2World,但是可以在以后连接到一个b2Body,为什么不传递b2BodyDefs,或者指向它们的指针呢
我可能会为b2BodyDef创建一个薄包装,例如:
请注意,我可以将此b2BodyDefWrapper附加到多个世界,或者多次附加到同一个世界
现在,您可能可以对b2BodyDef执行您无法对b2BodyDef执行的操作,因此传递(可能包装)b2BodyDefs w
World *w = new World;
Body *b = w->CreateBody(args);
Fixture *f = b->CreateFixture(args);
class Body {
int howBig;
String name;
Flavour flavour;
// and getter/setters
}
World {
Body makeBody(IndependentBody);
}
b2Body* b2World::CreateBody ( const b2BodyDef* def );
class b2BodyDefWrapper {
public const b2BodyDef& b2bodyDef;
public b2BodyDefWrapper( const b2BodyDef& bodydef ) : b2bodyDef(bodydef) {}
public const b2Body* reifyOn( b2World& world) const {
return world.CreateBody( b2bodyDef ) ;
}
}
class b2BodyDefWrapper {
private std::vector<Command&> commandStack;
public const b2BodyDef& b2bodyDef;
public b2BodyDefWrapper( const b2BodyDef& bodydef ) : b2bodyDef(bodydef) {}
public const b2Body* reify( b2World& world) const {
b2body* ret = world.CreateBody( &b2bodyDef ) ;
for (int i=0; i< commandStack.size(); i++) {
v[i].applyTo( ret ) ;
}
return ret;
}
public void addCommand( const Command& command ) {
commandStack.push_back( command );
}
}
class Command {
virtual ~Command() {}
virtual void applyTo( b2Body* body ) = 0 ;
}
class ApplyForce : public Command {
private const b2Vec2& force;
private const b2Vec2& point;
ApplyForce(const b2Vec2& f, const b2Vec2& p) : force(f), point(p) {}
virtual void applyTo( b2Body* body ) {
body->ApplyForce( force, point ) ;
}
}
extern b2BodyDef& makeb2BodyDef();
b2BodyDefWrapper w( makeb2BodyDef() ) ;
ApplyForce a( ..., ... );
w.addCommand( a ) ;
...
b2World myworld;
b2World hisWorld;
w.reifyOn( myWorld ) ;
w.reifyOn( hisWorld) ;
b2BodyDef myDef;
// fill out def
for (int i=0; i < 100; ++i) {
for (int j=0; j < 100; ++j) {
myDef.x = i;
myDef.y = j
b2Body* body = world.CreateBody(myDef)
}
}