2016-06-08 250 views
-1

我是C++的初學者,我想知道是否有訪問另一個對象成員的好方法。訪問另一個對象的成員

目前我使用這個訪問成員:

&_HeatSensor->IsOverheating == true; 
&_LeftLegSensor->IsStalled == true; 
/*... many more similar ones but different names*/ 

凡HeatSensor或LeftLegSensor是對象,而IsOverheating或IsStalled的名稱是該對象的布爾成員。

我想創建一個新的SensorOverLimit類,並創建了很多對象(例如:左腿,MotorTemperature ...等

爲了節省時間和重用的代碼,我希望能夠通過的東西,可以引用在構造函數中創建的布爾構件,然後通過引用或指針如在新SensorOverLimit對象的成員保存位置

SensorOverLimit.cpp

SensorOverLimit::SensorOverLimit(bool* SensorAddress) 
{ 
    bool* Sensor = SensorAddress; 
} 

SensorOverLimit::Check() 
{ 
    if (SensorAddress == true) 
    { 
     somefunction(); 
    } 
} 

main.cpp中:

SensorOverLimit Overheating = new SensorOverLimit(bool* &_HeatSensor->IsOverheating); 
SensorOverLimit DamagedLeg = new SensorOverLimit(bool* &_LeftLegSensor->IsStalled); 

這不起作用,有沒有人有任何想法如何讓這個工作?

+1

哪本書你從這個學習? – Nim

+0

另外,你爲什麼要通過「打擾」作爲指針?如果你只需要'City :: City(bool Disturb)',問題就簡單多了。 – kfsone

+0

人物和動物物體在其各自的人物和動物類別中具有各自的屬性。 kfsone,我可以做_person.IsDead並將其保存到我的邁阿密對象中的成員? – LilProgramma

回答

2

編輯:更改的問題,新的答案...

SensorOverLimit.h:

class SensorOverLimit 
{ 
    bool* sensor; 
public: 
    SensorOverLimit(bool* sensorAddress); 
    void check(); 
}; 

SensorOverLimit.cpp:

SensorOverLimit::SensorOverLimit(bool* sensorAddress) 
    : sensor(sensorAddress) 
{ 
} 

void SensorOverLimit::check() 
{ 
    if(*sensor) 
    { 
     somefunction(); 
    } 
} 

看一看雷米的回答爲參考,而不是指針(bool&而不是bool*,您可以忽略解引用(if(sensor)

main.cpp中:

HeatSensor heatSensor; 
LeftLegSensor leftLegSensor; 
SensorOverLimit overHeating(&heatSensor.isOverheating); 
SensorOverLimit leftLegDamaged(&leftLegSensor.isStalled); 

int main(int, char*[]) 
{ 
    // ... 
    return 0; 
} 

你可能已經注意到:我直接初始化的全局變量。這在嵌入式環境中通常更合適,至少易於使用。

小心處理開始以下劃線標識符 - 這是在許多情況下保留(C++標準,2.10):

包含雙下劃線__或以下劃線跟着是一個大寫字母開頭每個標識符保留給實施用於任何用途。

以下劃線開頭的每個標識符都保留給實現以用作全局名稱空間中的名稱。

編輯2:

我來了一個完全不同的設計,翻轉你有什麼至今:

class Sensor 
{ 
public: 
    Sensor() 
      : isActive(false) 
    { } 
    virtual ~Sensor() 
    { } 

    void check() 
    { 
     if(getValue() != isActive) 
     { 
      isActive = !isActive; 
      if(isActive) 
      { 
       someFunction(); 
      } 
     } 
    } 
private: 
    bool isActive; 
    virtual bool getValue() = 0; 
}; 

class HeatSensor : public Sensor 
{ 
    virtual bool getValue() 
    { 
     bool isActive = false; 
     // do what ever is necessary to detect overheat 
     // e. g. read from ADC and compare against threshold 
     return isActive; 
    } 
}; 

class LegSensor : public Sensor 
{ 
    bool isSignal; 
    virtual bool getValue() 
    { 
     // do what ever is necessary to detect stalled leg 
     // e. g.: simply returning the value that has been set from 
     // within an interrupt handler 
     return isSignal; 
    } 
}; 

不是真正的快樂我的成員的名字,你可能會發現更好的東西......


然而,這種設計的意圖是什麼?你打算遍歷每個城市,檢查布爾指針嗎?似乎是一個可疑的設計給我...

我提出一種替代你:

每個傳感器獲得一個SensorOverLimit *指針,你可以把它叫做「控制器」或什麼的似乎是適當的給你。然後爲每個傳感器類添加功能:oveheating(),stalling()等。在這些功能中,您可以調用SensorOverLimit新定義的功能:disturb(int reason, Sensor* source)。不是int,你可以定義一個包含所有可能的原因,如過熱,失速枚舉等

看起來是這樣的:

class Sensor; 

class SensorOverLimit 
{ 
    // appropriate members 
public: 
    enum Disturbance 
    { 
     Overheat, 
     Stall, 
    }; 

    SensorOverLimit() {} 

    void disturb(Disturbance reason, Sensor* source) 
    { 
     someFunction(); 
    } 
}; 

class Sensor 
{ 
protected: 
    SensorOverLimit* controller; 
public: 
    // ctor, getters, setters as needed 
    Sensor(SensorOverLimit* aController) : controller(aController) {} 
}; 

class HeatSensor : public Sensor 
{ 
public: 
    // ctor, getters, setters as needed 
    HeatSensor(SensorOverLimit* aController) : Sensor(aController) {} 
    void overheating() 
    { 
     if (controller) 
      controller->disturb(SensorOverLimit::Overheat, this); 
    } 
}; 

class LegSensor : public Sensor 
{ 
public: 
    // ctor, getters, setters as needed 
    LegSensor(SensorOverLimit* aController) : Sensor(aController) {} 
    void stalling() 
    { 
     if (controller) 
      controller->disturb(SensorOverLimit::Stall, this); 
    } 
}; 

SensorOverLimit controller; 
HeatSensor heatSensor(&controller); 
LegSensor leftLegSensor(&controller); 

int main(int, char*[]) 
{ 
    // ... 
    heatSensor.overheating(); 
    //... 
    leftLegSensor.stalling(); 
    //... 
    return 0; 
} 

優點:您可以將多個傳感器關聯到同一個控制器。

+1

'城市邁阿密=新....「當然?這不是java。 –

+0

對於需要了解多個傳感器狀態的嵌入式系統,每個傳感器都有自己的類,它只是簡化了不同的名稱,因此更易於閱讀。 – LilProgramma

+1

這確實解釋了這個問題的可能意圖,這似乎是一見鍾情的無關類的奇怪混合。 +1表示干擾的原因通知城市對象(並解決問題的內容)。 @LilProgramma更好地使用傳感器,控制器之類的真實名稱,或者讓別人瞭解你需要什麼。 –

0

爲什麼你不使用getter和setter來訪問你的對象的成員有一個特別的原因嗎?

如果您將所有對象引用爲指針,則可能需要重新考慮該操作。這StackOverflow問題提供了一些洞察常見的做法與C++和指針:Why should I use a pointer rather than the object itself?

我認爲你的問題的最佳答案實際上是熟悉指針的概念。這個問題以及我之前提到的問題給出了一個很好的起點 - C++ Objects: When should I use pointer or reference。我認爲最值得注意的一點是,如果您來自Java背景,指針和引用將隱藏在代碼中。每個對象都是一個指針,反之亦然。在C++中,它們是分開的。

我認爲你重複使用代碼的願望是值得讚揚的,但在這種情況下,使用指針可能會導致未知的錯誤!

我建議改變City類中的構造函數來實際處理對象,而不僅僅是它們的成員(例如,用一個人作爲參數創建一個城市,而不是這個人是活着還是死掉)。在面向對象編程中多做一點練習,你會發現它比你的初始方法容易得多!

+0

我只是想知道是否有一個簡單的可重用的方式來訪問不同的成員位置。我的更復雜的問題是將該Bool轉換爲自定義數據類型,該數據類型還包含一個函數,只要Bool發生變化,它就會發送一個QT信號告訴City對象它已經改變了狀態。因此,我需要引用IsDead中的connect()語句。 – LilProgramma

+0

@LilProgramma:這個糟糕的代碼設計讓你陷入了一個糟糕的兔子洞。我會讓每個人或動物包含一個指向他們所屬的城市的指針,如果人/動物去世,它可以直接通知城市。 –

+0

@LilProgramma就像澄清一樣,您的City對象是否包含您的所有人物和動物對象?現在看來,基於你想要做的事情,你需要在你的對象設計上做一些工作。如果你的人物和動物物體被包含在城市中,那麼做你想做的事情會容易得多。此外,雷米的評論是另一種(可能更好)的設計,取決於你想要你的對象是如何連接。 – tatertot

1

可以使用bool*指針這樣的:

class SensorOverLimit 
{ 
public: 
    bool* Sensor; 
    SensorOverLimit(bool* SensorAddress); 
    void Check(); 
}; 

... 

SensorOverLimit::SensorOverLimit(bool* SensorAddress) 
    : Sensor(SensorAddress) 
{ 
    Check(); 
} 

void SensorOverLimit::Check() 
{ 
    if (*Sensor) 
    { 
     somefunction(); 
    } 
} 

SensorOverLimit *Overheating = new SensorOverLimit(&(_HeatSensor->IsOverheating)); 
SensorOverLimit *DamagedLeg = new SensorOverLimit(&(_LeftLegSensor->IsStalled)); 
... 

然後,你可以這樣做:

_HeatSensor->IsOverheating = true; 
... 
Overheating->Check(); 

_LeftLegSensor->IsStalled = true; 
... 
DamagedLeg->Check(); 

隨着中說,這將是更安全的,而不是使用指針的引用:

class SensorOverLimit 
{ 
public: 
    bool& Sensor; 
    SensorOverLimit(bool& SensorAddress); 
    void Check(); 
}; 

... 

SensorOverLimit::SensorOverLimit(bool& SensorAddress) 
    : Sensor(SensorAddress) 
{ 
    Check(); 
} 

void SensorOverLimit::Check() 
{ 
    if (Sensor) 
    { 
     somefunction(); 
    } 
} 

SensorOverLimit *Overheating = new SensorOverLimit(_HeatSensor->IsOverheating); 
SensorOverLimit *DamagedLeg = new SensorOverLimit(_LeftLegSensor->IsStalled); 
... 

_HeatSensor->IsOverheating = true; 
... 
Overheating->Check(); 

_LeftLegSensor->IsStalled = true; 
... 
DamagedLeg->Check(); 
+0

正如我發現的那樣,他正在使用'&_name - >'因爲'name'是一個指針,他將其解除引用到它的'IsDead'成員,然後獲取它的地址。 – kfsone

+0

應該認爲我自己的參考... +1。 – Aconcagua