仅显示派生对象覆盖的函数

时间:2015-04-13 15:59:42

标签: c++ c++11 visual-studio-2013

我想只公开Abstract Class中被派生Class覆盖(实现)的函数。 例如:我有一个名为Abstract Class的{​​{1}},由各种不同类型的传感器实现。有些人比其他人有更多的能力,所以我不希望所有的功能都暴露出来。只有实施的。在以下示例中,所有传感器都可以生成DataA,但DataB和DataC是传感器特定的。有些可以产生全部三种,一些只有一些,有些只能产生DataA。

Sensor

有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:2)

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

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

不要忘记虚拟关键字。

示例:

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。比使用所需接口组合传感器(例如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();

您可以使用编译时间类型检查的功能。但是在这种情况下,如果您有基类SensorAB类,则只能投放到Sensor,而不能投放到SensorA或SensorB中。