Problemi di gestione della memoria della macchina

1

La mia macchina di stato gestisce le richieste e restituisce lo stato successivo. Nella semplificazione qui sotto, ho qui due stati, CreatedState e RunningState . Lo stato di esecuzione è lo stato finale e restituisce solo se stesso. Lo stato di esecuzione ha lo stato (come nei memebers) che deve essere presunto, userò il numero intero count per rappresentarli.

std::unique_pointer<StateBase> handle();

// Caller
void Call(){
    _currentState = _currentState->handle();
}

// Created State Implementation
std::unique_pointer<StateBase> CreatedState::handle(){
    return std::make_unique<RunningState>();
}

// Running State Implementation (option 1: create a new one)
std::unique_pointer<StateBase> RunningState::handle(){
    return std::make_unique<RunningState>(RunningState(int count));
}

Il problema qui è che creare un nuovo RunningState con un memento / tutti i membri privati del vecchio RunningState è disordinato e probabilmente inefficiente (?).

In una lingua gestita potrei solo return this , ma se facessi qualcosa del genere: return std::make_unique<RunningState>(&this) Avrei due puntatori allo stesso oggetto e la distruzione del lhs _currentState nella Call() lascerebbe io con niente a cui puntare.

Come posso lasciare in modo pulito ed efficiente _currentState invariato?

    
posta Nathan Cooper 23.10.2015 - 11:12
fonte

1 risposta

1

La mia soluzione potenziale:

Passa il puntatore come riferimento. Alterarlo nel manico secondo necessità. Non sono un grande fan dei parametri di mutazione in generale, ma penso che questa potrebbe essere la strada da percorrere?

#include <iostream>
#include <memory>

void handle2(std::unique_ptr<int>& current, bool changePtr)
{
    *current = *current + 5 ;
    if(changePtr){
    auto foo = std::make_unique<int>(200);
    (*foo)++;
    current = std::move(foo); //destruction of current only happens if I want to change state
    }
}

int main()
{
    auto currentState = std::make_unique<int>(50);

    handle2(currentState, false);
    std::cout << *currentState << std::endl; // 55
    // Guard against nullptr in caller      

    handle2(currentState, true);  
    std::cout << *currentState << std::endl; // 201

    handle2(currentState, false);    
    std::cout << *currentState << std::endl; // 206
}

Incidentalmente, ecco la macchina di stato che stavo progettando: link

    
risposta data 23.10.2015 - 15:00
fonte

Leggi altre domande sui tag