2015-03-11 5 views
-4

Я пытаюсь передать один экземпляр моего класса «Статус» ко всем моим другим классам, чтобы они могли установить и получить статус.Передайте экземпляр класса другому классу по ссылке

Я пытался сделать это, передав класс «Статус» по ссылке в мой класс «BaseStation». Код компилируется отлично, но когда я устанавливаю статус из main, а затем получаю статус в «BaseStation», он не изменился.

Я думаю, что это должно быть возможно, поэтому я должен что-то упустить.

Вот мой основной класс

#include "mbed.h" 
#include "Global.h" 
#include "MODSERIAL.h" 
#include "Status.h" 
#include "Sensors.h" 
#include "BaseStation.h" 
#include "Rc.h" 
#include "FlightController.h" 
#include "NavigationController.h" 

MODSERIAL       _debug(USBTX, USBRX); 

//Unused analog pins 
DigitalOut       _spare1(p16); 
DigitalOut       _spare2(p17); 
DigitalOut       _spare3(p18); 
DigitalOut       _spare4(p19); 

//Classes 
Status        _status; 
Sensors        _sensors; 
BaseStation       _baseStation; 
Rc         _rc; 
FlightController     _flightController; 
NavigationController    _navigationController;   

int main() 
{ 
    _debug.baud(115200); 

    DEBUG("\r\n"); 
    DEBUG("********************************************************************************\r\n"); 
    DEBUG("Starting Setup\r\n"); 
    DEBUG("********************************************************************************\r\n"); 

    //Set Status 
    _status.initialise(); 

    //Initialise RC 
    //_rc.initialise(_status, p8); 

    //Initialise Sensors 
    //_sensors.initialise(p13, p14, p28, p27); 

    //Initialise Navigation 
    //_navigationController.initialise(_status, _sensors, _rc); 

    //Initialise Flight Controller 
    //_flightController.initialise(_status, _sensors, _navigationController, p21, p22, p23, p24); 

    //Initalise Base Station 
    _baseStation.initialise(_status, _rc, _sensors, _navigationController, _flightController, p9, p10); 

    DEBUG("********************************************************************************\r\n"); 
    DEBUG("Finished Setup\r\n"); 
    DEBUG("********************************************************************************\r\n"); 

    _status.setState(Status::STANDBY); 
    int state = _status.getState(); 
    printf("Main State %d\r\n", state); 
} 

Вот мой Status.cpp

#include "Status.h" 

Status::Status(){} 

Status::~Status(){} 

bool Status::initialise() 
{ 
    setState(PREFLIGHT); 
    DEBUG("Status initialised\r\n"); 
    return true; 
} 

bool Status::setState(State state) 
{ 
    switch(state) 
    { 
     case PREFLIGHT: 
      setFlightMode(NOT_SET); 
      setBaseStationMode(STATUS); 
      setBatteryLevel(0); 
      setArmed(false); 
      setInitialised(false); 
      _state = PREFLIGHT; 
      DEBUG("State set to PREFLIGHT\r\n"); 
      return true; 

     case STANDBY: 

      _state = STANDBY; 
      DEBUG("State set to STANDBY\r\n"); 
      return true; 


     case GROUND_READY: 

      return true; 


     case MANUAL: 

      return true; 


     case STABILISED: 

      return true; 


     case AUTO: 

      return true; 


     case ABORT: 

      return true; 


     case EMG_LAND: 

      return true; 


     case EMG_OFF: 

      return true; 


     case GROUND_ERROR: 

      return true; 


     default: 

      return false; 

    }  
} 

Status::State Status::getState() 
{ 
    return _state;  
} 

bool Status::setFlightMode(FlightMode flightMode) 
{ 
    _flightMode = flightMode; 
    return true; 
} 

Status::FlightMode Status::getFlightMode() 
{ 
    return _flightMode; 
} 

bool Status::setBaseStationMode(BaseStationMode baseStationMode) 
{ 
    _baseStationMode = baseStationMode; 
    DEBUG("Base station mode set\r\n"); 
    return true; 
} 

Status::BaseStationMode Status::getBaseStationMode() 
{ 
    return _baseStationMode; 
} 

bool Status::setBatteryLevel(float batteryLevel) 
{ 
    _batteryLevel = batteryLevel; 
    return true; 
} 

float Status::getBatteryLevel() 
{ 
    return _batteryLevel; 
} 

bool Status::setArmed(bool armed) 
{ 
    _armed = armed; 
    return true; 
} 

bool Status::getArmed() 
{ 
    return _armed; 
} 

bool Status::setInitialised(bool initialised) 
{ 
    _initialised = initialised; 
    return true; 
} 

bool Status::getInitialised() 
{ 
    return _initialised; 
} 

bool Status::setRcConnected(bool rcConnected) 
{ 
    _rcConnected = rcConnected; 
    return true; 
} 

bool Status::getRcConnected() 
{ 
    return _rcConnected; 
} 

Вот мой status.h

#include "mbed.h" 
#include "Global.h" 

#ifndef Status_H 
#define Status_H 

class Status     // begin declaration of the class 
{ 
    public:     // begin public section 
    Status();  // constructor 
    ~Status();     // destructor 

    enum State 
    { 
     PREFLIGHT, 
     STANDBY, 
     GROUND_READY, 
     MANUAL, 
     STABILISED, 
     AUTO, 
     ABORT, 
     EMG_LAND, 
     EMG_OFF, 
     GROUND_ERROR  
    }; 

    enum FlightMode 
    { 
     RATE, 
     STAB, 
     NOT_SET 
    }; 

    enum BaseStationMode 
    { 
     MOTOR_POWER, 
     PID_OUTPUTS, 
     IMU_OUTPUTS, 
     STATUS, 
     RC, 
     PID_TUNING, 
     GPS, 
     ZERO, 
     RATE_TUNING, 
     STAB_TUNING, 
     ALTITUDE, 
     VELOCITY 
    }; 

    bool initialise(); 
    bool setState(State state); 
    State getState(); 
    bool setFlightMode(FlightMode flightMode); 
    FlightMode getFlightMode(); 
    bool setBaseStationMode(BaseStationMode baseStationMode); 
    BaseStationMode getBaseStationMode(); 
    bool setBatteryLevel(float batteryLevel); 
    float getBatteryLevel(); 
    bool setArmed(bool armed); 
    bool getArmed(); 
    bool setInitialised(bool initialised); 
    bool getInitialised(); 
    bool setRcConnected(bool rcConnected); 
    bool getRcConnected(); 

    private:    
    State _state; 
    FlightMode _flightMode;    
    BaseStationMode _baseStationMode; 
    float _batteryLevel; 
    bool _armed; 
    bool _initialised; 
    bool _rcConnected; 
}; 

#endif 

Вот мой BaseStation.cpp

#include "BaseStation.h" 

BaseStation::BaseStation() : _status(status){} 

BaseStation::~BaseStation(){} 

bool BaseStation::initialise(Status& status, Rc& rc, Sensors& sensors, NavigationController& navigationController, FlightController& flightController, PinName wirelessPinTx, PinName wirelessPinRx) 
{ 
    _status = status; 
    _rc = rc; 
    _sensors = sensors; 
    _navigationController = navigationController; 
    _flightController = flightController; 
    _wireless = new MODSERIAL(wirelessPinTx, wirelessPinRx); 
    _wireless->baud(57600); 
    _wirelessSerialRxPos = 0; 

    _thread = new Thread(&BaseStation::threadStarter, this, osPriorityHigh); 
    DEBUG("Base Station initialised\r\n"); 
    return true; 
} 

void BaseStation::threadStarter(void const *p) 
{ 
    BaseStation *instance = (BaseStation*)p; 
    instance->threadWorker(); 
} 

void BaseStation::threadWorker() 
{ 
    while(_status.getState() == Status::PREFLIGHT) 
    { 
     int state = _status.getState(); 
     printf("State %d\r\n", state); 
     Thread::wait(100); 
    } 

    _status.setBaseStationMode(Status::RC); 
} 

Вот мой BaseStation.h

#include "mbed.h" 
#include "Global.h" 
#include "rtos.h" 
#include "MODSERIAL.h" 
#include "Rc.h" 
#include "Sensors.h" 
#include "Status.h" 
#include "NavigationController.h" 
#include "FlightController.h" 

#ifndef BaseStation_H 
#define BaseStation_H 

class BaseStation     
{ 
    public:    
    BaseStation();  
    ~BaseStation(); 

    struct Velocity 
    { 
     float accelX; 
     float accelY; 
     float accelZ; 
     float gps; 
     float gpsZ; 
     float barometerZ; 
     float lidarLiteZ; 
     float computedX; 
     float computedY; 
     float computedZ; 
    };  

    bool initialise(Status& status, Rc& rc, Sensors& sensors, NavigationController& navigationController, FlightController& flightController, PinName wirelessPinTx, PinName wirelessPinRx); 

    private: 
    static void threadStarter(void const *p); 
    void threadWorker(); 
    void checkCommand(); 

    Thread* _thread; 
    MODSERIAL* _wireless; 
    Status& _status; 
    Status status; 
    Rc _rc; 
    Sensors _sensors; 
    NavigationController _navigationController; 
    FlightController _flightController; 
    char _wirelessSerialBuffer[255]; 
    int _wirelessSerialRxPos; 
}; 

#endif 

Выходной сигнал, когда я запускаю это

******************************************************************************** 
Starting Setup 
******************************************************************************** 
Base station mode set 
State set to PREFLIGHT 
Status initialised 
Rc initialised 
HMC5883L failed id check.IMU initialised 
Sensors initialised 
State 0 
Base Station initialised 
******************************************************************************** 
Finished Setup 
******************************************************************************** 
State set to STANDBY 
Main State 1 
State 0 
State 0 

Я думаю, это потому, что я на самом деле не проходит ни одного экземпляра «Status», но копируя его.

Как я могу передать по ссылке правильно?

Благодаря Джо

+0

Посмотрите www.sscce.org – Bathsheba

+6

Я голосую, чтобы закрыть этот вопрос как вне темы, потому что слишком много кода. – Bathsheba

+0

'_status = status;' Упс. –

ответ

1
int x = 42; 
int y = 9001; 

int& r = x; 
r = y; 

Теперь x является 9001. Вы ничего не изменили о r.

Аналогичным образом, в вашем коде, хотя вы принимаете Status по ссылке, вы затем присваиваете его значение другому объекту.

Возможно только Инициализация ссылок.В вашем случае вы хотите связать их.

Вот как вы делаете то, что вы хотите сделать:

struct Status {}; 
struct T 
{ 
    T(Status& _ref) // 1. Accept parameter by reference; 
     : ref(_ref) // 2. Initialise member reference; 
    {}    // now this->ref is a reference to whatever _ref was a reference to 

    Status& ref; 
}; 

int main() 
{ 
    Status s; 
    T obj(s); // now obj holds a reference to s 
} 
+0

Спасибо всем, поэтому в основном вы можете передавать только по ссылке в конструкторе. Cheers –

+0

@JosephBaldwinRoberts: Это не совсем то, что мы говорим, нет. –

0

Вы полностью поняли, как ссылки на работы в C++. Вы можете установить ссылку только в конструкторе и только в списке инициализации члена, в любом другом месте, где вы назначаете объект, на который указывает эта ссылка. Так

BaseStation::BaseStation() : _status(status){} 

Теперь ваши опорные точки к члену status

bool BaseStation::initialise(Status& status, Rc& rc, Sensors& sensors, NavigationController& navigationController, FlightController& flightController, PinName wirelessPinTx, PinName wirelessPinRx) 
{ 
    _status = status; 

Теперь вы задание на объект, где _status указывает. Так что этот код на самом деле эквивалентен:

bool BaseStation::initialise(Status& status, Rc& rc, Sensors& sensors, NavigationController& navigationController, FlightController& flightController, PinName wirelessPinTx, PinName wirelessPinRx) 
{ 
    this->status = status; 

Это не очень хорошая идея, чтобы заменить конструктор по инициализации методы в целом, но в случае, если у вас есть ссылка, это еще хуже. Вам нужно либо изменить его на указатель, либо правильно инициализировать свои объекты - в конструкторе.

Смежные вопросы