gpt4 book ai didi

c++ - 仅公开派生对象覆盖的函数

转载 作者:太空狗 更新时间:2023-10-29 21:41:11 24 4
gpt4 key购买 nike

我只想公开抽象类 中已被派生 覆盖(实现)的函数。例如:我有一个名为 SensorAbstract Class,它由各种不同类型的传感器实现。有些功能比其他功能更多,所以我不希望公开所有功能。只有实现的。在以下示例中,所有传感器都可以生成 DataA,但 DataB 和 DataC 是特定于传感器的。有些可以生成所有三个,有些可以生成 2,有些只能生成 DataA。

    //Code Example
class Sensor{
public:
virtual DataContainer* getDataA() = 0; //pure virtual
virtual DataContainer* getDataB() {return null_ptr;}; //but this would appear in the derived objects
virtual DataContainer* getDataC() {return null_ptr;};
}

class SensorA : public Sensor {
public:
virtual DataContainer* getDataA(){
//code
}
}

class SensorAB : public Sensor {
public:
virtual DataContainer* getDataA(){
//code
}
virtual DataContainer* getDataB(){
//code
}
}

//main
Sensor* ab = new SensorAB();
ab->getDataB(); //GOOD
ab->getDataC(); // Not possible

有什么办法可以实现吗?

最佳答案

您需要更深的类层次结构。

class Sensor...
class SensorA: virtual public Sensor...
class SensorB: virtual public Sensor...
class SensorAB: public SensorA, public SensorB...

不要忘记 virtual 关键字。

例子:

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

template<typename T>
bool CanConvert()
{
return dynamic_cast<T*>(this) != nullptr;
}

template<typename T>
T& Convert()
{
return dynamic_cast<T>(*this);
}
};

class SensorA: virtual public Sensor {
public:
virtual void DataA() = 0;
};

class SensorB: virtual public Sensor {
public:
virtual void DataB() = 0;
};

class SensorC: virtual public Sensor {
public:
virtual void DataC() = 0;
};

class SensorAB: public SensorA, public SensorB {
public:
void DataA() override {
std::cout << "SensorAB::DataA()" << std::endl;
}
void DataB() override {
std::cout << "SensorAB::DataB()" << std::endl;
}
};

你可以使用它:

void Func(Sensor& s)
{
if (s.CanConvert<SensorA>()) {
auto &s_a = s.Convert<SensorA>();
s_a.DataA();
}

if (s.CanConvert<SensorB>()) {
auto &s_b = s.Convert<SensorB>();
s_b.DataB();
}

if (s.CanConvert<SensorC>()) {
auto &s_c = s.Convert<SensorC>();
s_c.DataC();
}
}
...
SensorAB s_ab;
Func(s_ab);

或者你可以使用静态多态。为每种数据类型创建基类:SensorA、SensorB、SensorC。然后用所需的接口(interface)组合传感器(例如 SensorAB):

template <class Derived>
class SensorA
{
public:
void DataA() { static_cast<Derived*>(this)->DataAImpl(); }
};

template <class Derived>
class SensorB
{
public:
void DataB() { static_cast<Derived*>(this)->DataBImpl(); }
};

template <class Derived>
class SensorC
{
public:
void DataC() { static_cast<Derived*>(this)->DataCImpl(); }
};

class SensorAB: public SensorA<SensorAB>, public SensorB<SensorAB>
{
public:
void DataAImpl()
{
std::cout << "SensorAB::DataAImpl()" << std::endl;
}

void DataBImpl()
{
std::cout << "SensorAB::DataBImpl()" << std::endl;
}
};

你可以使用它:

SensorAB s_ab;
s_ab.DataA();
s_ab.DataB();

并且您可以使用编译时类型检查的强大功能。但在这种情况下,如果您有基础 Sensor 类,则只能转换为 SensorAB,而不能转换为 SensorA 或 SensorB。

关于c++ - 仅公开派生对象覆盖的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29609860/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com