-4

「ステータス」クラスの単一のインスタンスを他のすべてのクラスに渡して、すべてのクラスがステータスを設定および取得できるようにしようとしています。

「Status」クラスを参照によって「BaseStation」クラスに渡すことで、これを実行しようとしました。コードは正常にコンパイルされますが、メインからステータスを設定してから「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

これは、実際には「ステータス」の単一のインスタンスを渡しているのではなく、コピーしているためだと思います。

どうすれば参照渡しを適切に行うことができますか?

ありがとうジョー

4

2 に答える 2

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
}
于 2015-03-11T15:35:13.703 に答える
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;

一般に、コンストラクターを初期化メソッドで置き換えることはお勧めできませんが、参照がある場合はさらに悪いことです。それをポインターに変更するか、コンストラクターでオブジェクトを適切に初期化する必要があります。

于 2015-03-11T15:32:52.103 に答える