C++ C++;继承类,并将修改后的参数发送到父级';s构造函数
我想创建类继承,在这里我的新类创建父类的对象,设置一些默认参数(它们是指向其他对象的指针) 一开始我有:C++ C++;继承类,并将修改后的参数发送到父级';s构造函数,c++,class,pointers,inheritance,constructor,C++,Class,Pointers,Inheritance,Constructor,我想创建类继承,在这里我的新类创建父类的对象,设置一些默认参数(它们是指向其他对象的指针) 一开始我有: btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); btVec
btDefaultCollisionConfiguration* collisionConfiguration =
new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btVector3 worldAabbMin(-1000,-1000,-1000);
btVector3 worldAabbMax(1000,1000,1000);
btAxisSweep3* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax);
colWorld = new btCollisionWorld(dispatcher,broadphase,collisionConfiguration);
colWorld->setDebugDrawer(dbgdraw);
我想要一些像:
colWorld = new myBtCollisionWorld(dbgdraw);
我尝试了很多东西,发明了一个小把戏
btVector3 worldAabbMin;
btVector3 worldAabbMax;
class BtOgreCollisionWorld_initializer { //A trick: we need one more constructor to
// initialize default variables; Then we will pass them to btCollisionWorld
// as it stands next in inheritance list
public:
BtOgreCollisionWorld_initializer(btCollisionDispatcher *&dispatcher,
btAxisSweep3 *&broadphase,
btDefaultCollisionConfiguration *&collisionConfiguration)
{
if (!worldAabbMin) worldAabbMin = btVector3(-1000,-1000,-1000);
if (!worldAabbMax) worldAabbMax = btVector3(1000,1000,1000);
if (!collisionConfiguration)
collisionConfiguration = new btDefaultCollisionConfiguration();
if (!dispatcher)
dispatcher = new btCollisionDispatcher(collisionConfiguration);
if (!broadphase) broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax);
};
};
class BtOgreCollisionWorld: public BtOgreCollisionWorld_initializer,
public btCollisionWorld {
public:
//using btCollisionWorld::btCollisionWorld;
BtOgreCollisionWorld(BtOgre::DebugDrawer *dbgdraw,
btCollisionDispatcher* dispatcher = 0, btAxisSweep3* broadphase = 0,
btDefaultCollisionConfiguration* collisionConfiguration = 0)
: BtOgreCollisionWorld_initializer(dispatcher, broadphase,
collisionConfiguration),
btCollisionWorld(dispatcher, broadphase, collisionConfiguration)
{
/*copying variables above*/
this->setDebugDrawer(dbgdraw);
};
protected:
btDefaultCollisionConfiguration* collisionConfiguration;
btCollisionDispatcher* dispatcher;
btVector3 worldAabbMin;
btVector3 worldAabbMax;
btAxisSweep3* broadphase;
};
这背后的想法是首先调用“初始值设定项”类构造函数,并覆盖btCollisionWorld类的变量
突然,它起了作用
我知道这似乎是一个尝试,开始一个毫无意义的讨论,但我不熟练的C++,并没有发现任何类似的谷歌,因为它;因此,我只是好奇是否有任何可能的陷阱或其他实现方法。它似乎过于复杂。从设置了一些硬编码值的类继承看起来不太好。如果您确实希望派生类在逻辑上是独立的(基于init参数),那么最好将其模板化。它将允许您基于不同的初始化参数创建更多这样的类 它似乎过于复杂了。从设置了一些硬编码值的类继承看起来不太好。如果您确实希望派生类在逻辑上是独立的(基于init参数),那么最好将其模板化。它将允许您基于不同的初始化参数创建更多这样的类 它似乎过于复杂了。从设置了一些硬编码值的类继承看起来不太好。如果您确实希望派生类在逻辑上是独立的(基于init参数),那么最好将其模板化。它将允许您基于不同的初始化参数创建更多这样的类 它似乎过于复杂了。从设置了一些硬编码值的类继承看起来不太好。如果您确实希望派生类在逻辑上是独立的(基于init参数),那么最好将其模板化。它将允许您基于不同的初始化参数创建更多这样的类 以下是我的理解(如果我错了,请告诉我,我将删除答案): 你的设计似乎很复杂。起初我以为你没有利用遗产。但后来我意识到问题应该更复杂。以下是我的理解: 您有一个基类,其构造函数依赖于它的环境(例如一些外部变量)。我尝试用一个更简单的例子:
Dispatcher* dispatcher = new Dispatcher(xyz); // global parameter
class World {
private:
Dispatcher *my_dispatcher; // some private that you can't change later on
public:
World() {
my_dispatcher = dispatcher; // take over the global.
...
}
...
};
然后,您希望派生一个类,其构造函数参数应该会影响基类的环境
class DWorld : public World {
public:
DWorld(Dispatcher* d) : World() {
dispatcher = d; // too late: the base is already created !!!
...
}
...
};
该逻辑在标准中定义:
- 基类部分总是在派生类之前构造
- 首先执行基初始值设定项(如果不是默认的基构造函数,则可能初始化基),然后执行其他成员,然后才执行构造函数的主体指令李>
class Helper {
public:
Helper (Dispatcher* d) {
dispatcher = d;
// do whatever you want to do before World base is intialized
}
};
class DWorld : public Helper, public World {
public:
DWorld(Dispatcher* d) : Helper(d), World() {
... // everything is fine
}
...
};
这不是巧合:这也是C++标准中非常精确的定义:在多重继承的情况下,基元初始化器按照继承语句中定义的顺序操作。所以在这里,首先是
Helper
,然后是World
但是,您必须处理多重继承,这可能会很困难,尤其是在继承树的几个不同层上需要相同的助手时
现在还有一个窍门:
不幸的是,它在一个条件下工作:基本构造函数必须至少接受一个参数
假设我有一个构造函数世界(inta
)。在这种情况下,我可以使用一个helper函数来避免多重继承:
int helper(Dispatcher*d, int a) {
dispatcher = d;
return a;
}
class DWorld : public World { // single inheritance
public:
DWorld(Dispatcher* d) : World(helper(0)) { } // but function pipeline !
};
这是因为必须首先对函数求值才能调用World
构造函数
带有lambda函数的变体虽然可读性较差,但允许您捕获范围内的任何变量,并将其用作最佳匹配:
DWorld(Dispatcher* d) : World([&]()->int {dispatcher = d; return 0; }()) {...}
结论
这里有一些工具可以解决你的急迫问题。然而,诡计仍然是诡计。这是一个解决办法。他认为最好的解决方案是重新设计基类 以下是我的理解(如果我错了,请告诉我,我将删除答案): 你的设计似乎很复杂。起初我以为你没有利用遗产。但后来我意识到问题应该更复杂。以下是我的理解: 您有一个基类,其构造函数依赖于它的环境(例如一些外部变量)。我尝试用一个更简单的例子:
Dispatcher* dispatcher = new Dispatcher(xyz); // global parameter
class World {
private:
Dispatcher *my_dispatcher; // some private that you can't change later on
public:
World() {
my_dispatcher = dispatcher; // take over the global.
...
}
...
};
然后,您希望派生一个类,其构造函数参数应该会影响基类的环境
class DWorld : public World {
public:
DWorld(Dispatcher* d) : World() {
dispatcher = d; // too late: the base is already created !!!
...
}
...
};
该逻辑在标准中定义:
- 基类部分总是在派生类之前构造
- 首先执行基初始值设定项(如果不是默认的基构造函数,则可能初始化基),然后执行其他成员,然后才执行构造函数的主体指令李>
class Helper {
public:
Helper (Dispatcher* d) {
dispatcher = d;
// do whatever you want to do before World base is intialized
}
};
class DWorld : public Helper, public World {
public:
DWorld(Dispatcher* d) : Helper(d), World() {
... // everything is fine
}
...
};
这不是巧合:这也是C++标准中非常精确的定义:在多重继承的情况下,基元初始化器按照继承语句中定义的顺序操作。所以在这里,首先是
Helper
,然后是World
然而,您必须处理多重继承,这可能是