通过引用将 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;
现在 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
}
我正在尝试将我的 "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;
现在 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
}