簡體   English   中英

為什么此代碼的打印順序無法按我預期的方式工作?

[英]Why do the print sequence of this code does not work as I expected?

我有一個System類(以ISystem作為接口),其中包含一個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;
        }
    }
};

首先,我創建一個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

為什么會這樣?

因為當您輸入以下內容時:

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;

警告

但這實質上意味着對象的構造函數內部調用A對象上的delete ,這聽起來有點錯誤。 您可能需要重新考慮這個想法(從“原始指針永遠不要擁有資源”准則開始)。

在輸出消息之前,請創建新的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

您調用system.stateChanged(0); 調用ControllerA的構造函數,該構造函數調用system.stateChanged(1);

ControllerB的構造函數不執行任何操作,因此您最終將打印"state 1 with ControllerB\\n"返回到第一個stateChanged調用,並在那里打印"state 0 with ControllerA\\n"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM