我是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);
这不起作用,有没有人对如何使其发挥作用有任何想法?
答案 0 :(得分: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();
}
}
请查看Remy对引用的回答而不是指针(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;
}
};
对我的会员名字不太满意,你可能会找到更好的东西......
然而,您对此设计的意图是什么?你打算遍历每个城市,查看bool指针吗?对我来说似乎有问题......
我建议你替代:
每个Sensor都会获得一个SensorOverLimit *指针,您可以将其称为“控制器”或任何适合您的指针。然后向每个Sensor类添加函数:oveheating()
,stalling()
等。在这些函数中,您调用SensorOverLimit的新定义函数:disturb(int reason, Sensor* source)
。您可以定义包含所有可能原因的枚举,而不是int,例如Overheat,Stall等。
看起来像这样:
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 :(得分: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();
答案 2 :(得分: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背景,那么指针和引用将隐藏在代码中。 Java中的每个对象都是指针,反之亦然。在C ++中,它们是分开的。
我认为您重用代码的愿望是值得称道的,但在这种情况下,使用指针可能会导致未知错误!
我建议您更改City类中的构造函数以实际处理对象,而不仅仅是其成员(例如,创建一个以人为参数的城市,而不是该人是活着还是已死) 。通过在面向对象编程中进行更多练习,您可能会发现它比初始方法更容易!