我有一个类System(ISystem as interface),它包含一个Controller,ControllerA或ControllerB。系统可以通过调用stateChanged:
来切换控制器#include <stdio.h>
class ISystem{
public:
virtual void stateChanged(int state)=0;
};
class Controller{};
class ControllerA : public Controller{
public:
ControllerA(ISystem* system){
system->stateChanged(1);
}
};
class ControllerB : public Controller{
public:
ControllerB(ISystem* system){}
};
class System : public ISystem{
protected:
Controller* controller;
public:
System(){this->controller=NULL;}
void stateChanged(int state){
if(controller!=NULL){
delete controller;
}
switch(state){
case 0:
controller=new ControllerA(this);
printf("state 0 with ControllerA\n");
break;
case 1:
controller=new ControllerB(this);
printf("state 1 with ControllerB\n");
break;
}
}
};
在main中,我创建一个System并将其设置为状态0,然后它应该首先创建ControllerA,然后在ControllerA中调用stateChanged(1)以切换到ControllerB:
int main(){
System system;
system.stateChanged(0);
return 0;
}
所以我希望输出是:
state 0 with ControllerA
state 1 with ControllerB
但结果输出序列是:
state 1 with ControllerB
state 0 with ControllerA
为什么会发生这种情况?
答案 0 :(得分:2)
因为当你输入这个:
case 0:
controller=new ControllerA(this);
printf("state 0 with ControllerA\n");
break;
首先调用A
的c-tor,调用它:
system->stateChanged(1);
反过来这样做:
case 1:
controller=new ControllerB(this);
printf("state 1 with ControllerB\n");
break;
但这实际上意味着delete
对象上的A
从其构造函数中被称为,这听起来有点不对。您可能想重新考虑这个想法(从“原始指针不应该拥有资源”指南开始)。
答案 1 :(得分:0)
您在输出消息之前创建新的ControllerA
。也许你的意思是:
void stateChanged(int state){
if(controller!=NULL){
delete controller;
}
switch(state){
case 0:
printf("state 0 with ControllerA\n"); //print before creating
controller=new ControllerA(this);
break;
case 1:
printf("state 1 with ControllerB\n"); //ditto
controller=new ControllerB(this);
break;
}
}
虽然你应该在C ++中使用std::cout
而不是printf
。
答案 2 :(得分:0)
您致电system.stateChanged(0);
调用ControllerA的构造函数,该构造函数调用system.stateChanged(1);
。
ControllerB的构造函数不执行任何操作,因此您最终打印"state 1 with ControllerB\n"
返回到第一个stateChanged
调用并在那里打印"state 0 with ControllerA\n"
。