【发布时间】:2021-07-13 22:21:17
【问题描述】:
我试图定义一个接口(抽象类),它将“自动”注册任何创建到全局映射的实例,其中键是 uint8_t,值是指向接口类的指针。
将实现此接口的所有类都已具有使用getId() 方法检索唯一ID 的方法。我尝试了以下方法,但是当我在接口的 c'tor 和 d'tor 中使用(当时)抽象方法 getId() 时,它会收到警告,我可以理解。但是当我尝试创建 LightZoneImpl 的实例时出现错误,因为它没有实现 getId()。
我在这里做错了什么?
注意:这是真实事物的简化示例,真实事物中涉及许多其他类等。
class ILightZone; // forward
typedef std::map<uint8_t, ILightZone*> LightZoneMap;
extern LightZoneMap lightZoneMap;
/**
* @brief Interface defining a Lightzone operating node, automatically (de-)registered in the lightZoneMap
*
*/
class ILightZone {
public:
ILightZone() {
lightZoneMap[getId()] = this; // <== warning: pure virtual function called from c'tor
}
virtual ~ILightZone() {
lightZoneMap.erase(getId()); // <== warning: pure virtual function called from d'tor
}
virtual const uint8_t getId() const = 0;
virtual void setLightOn() = 0;
virtual void setLightOff() = 0;
virtual bool isLightOn() = 0;
virtual void setIntensity(const uint8_t percentage) = 0;
virtual uint8_t getIntensity() = 0;
};
class BaseNode {
public:
BaseNode(uint8_t nodeId) : nodeId(nodeId) {};
virtual ~BaseNode() {};
virtual const uint8_t getid() const { return nodeId; };
private:
uint8_t nodeId;
};
class LightZoneImpl : public ILightZone, public BaseNode {
public:
LightZoneImpl() {};
virtual ~LightZoneImpl() {};
using BaseNode::getId;
void setLightOn() override { /* implementation */};
void setLightOff() override { /* implementation */};
bool isLightOn() override { return false; };
void setIntensity(const uint8_t percentage) override { /* implementation */ };
uint8_t getIntensity() override { return 0; };
}
LightZoneImpl zone{12}; // <= error: cannot declare variable 'zone' to be of abstract type LightZoneImpl
注意2:修改下面的示例以显示下面建议的解决方案
class ILightZone; // forward
typedef std::map<uint8_t, ILightZone*> LightZoneMap;
extern LightZoneMap lightZoneMap;
/**
* @brief Interface defining a Lightzone operating node, automatically (de-)registered in the lightZoneMap
*
*/
class ILightZone {
public:
ILightZone(uint8_t nodeId) : nodeId(nodeId) {
lightZoneMap[nodeId] = this;
}
virtual ~ILightZone() {
lightZoneMap.erase(nodeId);
}
const uint8_t getId() const { return nodeId; };
virtual void setLightOn() = 0;
virtual void setLightOff() = 0;
virtual bool isLightOn() = 0;
virtual void setIntensity(const uint8_t percentage) = 0;
virtual uint8_t getIntensity() = 0;
private:
uint8_t nodeId;
};
class BaseNode {
public:
BaseNode(uint8_t nodeId) : nodeId(nodeId) {};
virtual ~BaseNode() {};
virtual const uint8_t getid() const { return nodeId; };
private:
uint8_t nodeId;
};
class LightZoneImpl : public ILightZone, public BaseNode {
public:
LightZoneImpl(uint8_t nodeId) : ILightZone(nodeId), BaseNode(nodeId) {};
virtual ~LightZoneImpl() {};
using BaseNode::getId;
void setLightOn() override { /* implementation */};
void setLightOff() override { /* implementation */};
bool isLightOn() override { return false; };
void setIntensity(const uint8_t percentage) override { /* implementation */ };
uint8_t getIntensity() override { return 0; };
}
LightZoneImpl zone{12}; // <= error: cannot declare variable 'zone' to be of abstract type LightZoneImpl
【问题讨论】:
-
您未能声明
BaseNode::getId。