我有一个关于多态性的问题。
这是我代码的重要部分。
如果我的问题很愚蠢,我很抱歉,但我不明白如何在这种方法中使用多态性:
Val_Type Sensor_Map::Get_Last_Value(const std::string &_Nome_Fisico) const
我知道return iter->second.Get_Last_Value();
不正确,因为多态性仅在通过指针访问该方法时才有效。我尝试这样做:
const Sensor *S = &(iter->second);
return S->Get_Last_Value();
但它在temperature_Sensor
方法中调用传感器的方法。 当我做Sensori.insert(std::pair<std::string, Sensor>(_Nome_Fisico, *S));
时,问题会在工厂制造内部吗?在这种情况下,我应该在实例中存储一个指针(并更改很多代码:((,但是在SensorMap::Insert()
结束时,新实例超出了范围,我可以有悬空指针吗?
typedef float Val_Type;
class Sensor
{
private:
Val_Type Last;
........
public:
virtual Val_Type Get_Last_Value() const;
........
};
class Temperature_Sensor:public Sensor
{
........
public:
Val_Type Get_Last_Value() const;
........
};
Val_Type Sensor::Get_Last_Value() const
{return Last;}
Val_Type Temperature_Sensor::Get_Last_Value() const
{ return ((Last * (Tempeartura_Max - Tempeartura_Min) / 1024) + Tempeartura_Min );}
class Sensor_Map
{
private:
........
std::map<std::string,Sensor>Sensori;
public:
........
inline Val_Type Get_Last_Value(const std::string &_Nome_Fisico) const;
};
void Sensor_Map::Insert(const std::string &_Nome_Fisico)
{
// FACTORY MADE for sensor type
char type;
type=_Nome_Fisico[0]; // first character set the type
switch(type)
{
case 's':
{ // creo un nuovo sensore base
Sensor *S = new Sensor(_Nome_Fisico);
Sensori.insert(std::pair<std::string, Sensor>(_Nome_Fisico, *S));
delete S; // deallocazione memoria dinamica
break;
}
case 't':
{ // creo un nuovo Temperature_Sensor
Sensor *S = new Temperature_Sensor(_Nome_Fisico);
Sensori.insert(std::pair<std::string, Sensor>(_Nome_Fisico, *S));
delete S; // deallocazione memoria dinamica
break;
}
}
}
Val_Type Sensor_Map::Get_Last_Value(const std::string &_Nome_Fisico) const
{
std::map<std::string,Sensor>::const_iterator iter = Sensori.find(_Nome_Fisico);
if(iter !=Sensori.end())
{ // <== MY PROBLEM IS HERE ####################################
// i would like to return the member "Last" of the sensor pointed by iter->second through the more specific methods
}
}
非常感谢您的耐心等待,有好的一天
需要在Sensori
地图中存储指针。也就是说,它应该是 std::map<std::string,Sensor*>
型或更好的 std::map<std::string, std::shared_ptr<Sensor>>
.更喜欢第二种变体,因为它让您不必担心内存泄漏和过早释放对象,从而使您的生活更加轻松。
您的程序现在存在在Sensori
中插入Temperature_Sensor
时对象切片的问题。您的Sensori
地图现在存储Sensor
对象,而不是任何传感器子类型的对象。现在获取存储对象的地址并希望它指向Temperature_Sensor
有点晚了。您分配的Temperature_Sensor
已被切掉,仅此而已。
代码类似
Sensor *S = Sensor(_Nome_Fisico);
Sensori.insert(std::pair<std::string, Sensor>(_Nome_Fisico, *S));
delete S; // deallocazione memoria dinamica
可以这样表达
Senor S(whatever);
Sensori.insert(std::pair<std::string, Sensor>(whatever, S));
// no delete
但无论如何都是错误的(见上文关于对象切片的信息(,你需要这个
std::shared_ptr<Sensor> S (std::make_shared<Sensor>(whatever));
Sensori[whatever] = S; // note no verbose iterator syntax
// no delete, ever
最后但并非最不重要的一点是,不要使用前导下划线后跟大写字母(如_Nome_Fisico
(,因为此类名称是为实现保留的。