C++ 通过引用将类实例传递给另一个类

C++ 通过引用将类实例传递给另一个类,c++,dependency-injection,pass-by-reference,mbed,C++,Dependency Injection,Pass By Reference,Mbed,我试图将我的“Status”类的一个实例传递给所有其他类,以便它们都可以设置和获取状态 我一直试图通过引用将“Status”类传递到我的“BaseStation”类来实现这一点。代码编译得很好,但是当我从main设置状态,然后在“BaseStation”中获取状态时,它没有改变 我想这应该是可能的,所以我肯定错过了什么 这是我的主课 #include "mbed.h" #include "Global.h" #include "MODSERIAL.h" #include "Status.h" #

我试图将我的“Status”类的一个实例传递给所有其他类,以便它们都可以设置和获取状态

我一直试图通过引用将“Status”类传递到我的“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);
}
这是我的状态

#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;
}
这是我的状态

#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
这是我的基站

#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);
}
这是我的基站

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

我怎样才能正确地通过引用

谢谢

< P>你完全误解C++中引用是如何工作的。您只能在构造函数中设置引用,也只能在成员初始化列表中设置引用,即您对引用指向的对象进行赋值的任何其他位置。所以

BaseStation::BaseStation() : _status(status){}
现在,您的参考点指向会员
状态

bool BaseStation::initialise(Status& status, Rc& rc, Sensors& sensors, NavigationController& navigationController, FlightController& flightController, PinName wirelessPinTx, PinName wirelessPinRx)
{   
    _status = status;
现在您将赋值给对象,其中的
\u status
指向。所以这个代码实际上相当于:

bool BaseStation::initialise(Status& status, Rc& rc, Sensors& sensors, NavigationController& navigationController, FlightController& flightController, PinName wirelessPinTx, PinName wirelessPinRx)
{   
    this->status = status;
一般来说,用initialize方法替换构造函数不是一个好主意,但若你们有引用,那个就更糟了。您需要将其更改为指针,或者在构造函数中正确初始化对象

int  x = 42;
int  y = 9001;

int& r = x;
r = y;
现在
x
9001
。关于
r
,您没有做任何更改

类似地,在代码中,尽管您通过引用接受
状态
,但随后将其值指定给不同的对象

您只能初始化引用。在你的情况下,你想把他们锁起来

以下是你如何做你想做的事情:

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
}

请访问www.sscce.org,因为代码太多,所以我投票将此问题作为离题题题结束。
\u status=status哎呀。代码太多了。当你注册时,你就学会了如何提问和提供MCVE。遗憾的是,你没有费心阅读这些材料。谢谢大家,所以基本上你只能在构造函数中通过引用传递。Cheers@JosephBaldwinRoberts当前位置我们不是这么说的,不是。