通过引用将 class 实例传递给另一个 class

Pass a class instance to another class by reference

我正在尝试将我的 "Status" class 的单个实例传递给所有其他 classes,以便它们都可以设置和获取状态。

我一直在尝试通过引用将 "Status" class 传递到我的 "BaseStation" class 中来做到这一点。代码编译正常,但是当我从 main 设置状态然后在 "BaseStation" 中获取状态时,它没有改变。

我认为这应该是可能的,所以我一定是遗漏了什么。

这是我的主要内容class

#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" 的单个实例,而是复制了它。

如何正确传递引用?

谢谢 乔

您完全误解了引用在 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;

一般情况下用initialize方法代替constructor不是一个好主意,但如果你有参考,那就更糟了。您需要将其更改为指针,或在构造函数中正确初始化您的对象。

int  x = 42;
int  y = 9001;

int& r = x;
r = y;

现在 x9001。您没有对 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
}