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

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

我只想公开抽象类 中已被派生 覆盖(实现)的函数。 例如:我有一个名为 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/

相关文章:

c++ - 无需解码所有数据即可获取 gif 帧数

c++ - 错误 C2065 : But it is for sure declared

OpenCV 构建问题 Visual Studio 2013

c# - 部署到 "C:\Program Files\..."后,我的应用程序无法更新 Access 数据库

c# - 在 SQL 查询中包含文本框值

c++ - 当我在 Code::Blocks 中有来自同一组源文件的两个 .cpp 文件时,如何运行其中一个?

c++ - Visual Studio 中嵌套模板函数的 typeid 不一致

c++ - 我还需要对 algorithm::join 使用 boost 吗?

c++ - 使用 ping 实用程序的 Qt QProccess

c++ - move 构造函数不能默认