2016-06-08 162 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