C++:编译时和运行时不允许派生类中的虚拟函数

C++: disallowing virtual function in derived class at compile vs runtime

本文关键字:虚拟 函数 派生 不允许 编译 运行时 C++      更新时间:2023-10-16

我有一个具有方法void setup(const int* p)的父class RO。我需要一个子class RW有相同的方法,只允许非常量指针。

我通过在class RO中创建两个方法并在class RW:中禁用其中一个方法来实现这一点

class RO
{
public:
    void setup(int* p) { DO SMTH }
    virtual void setup (const int* p) { RO::setup( const_cast<int*>(p) ); }
    // the rest...
    void read() const;
};
class RW : public RO
{
public:
    virtual void setup (const int* p) { throw SMTH }
    // the rest...
    void write();
};

如果可能的话,我希望能够在编译时禁止RW::setup。即

const int* p;
RO* ro = new RW;
ro->setup(p);        // Throw at run time, since it can be unknown
                     // at compile time that ro points to RW and not to RO.
RW* rw = new RW;
rw->f(p);            // Disallow this at compile time, since it is
                     // known at compile time that rw points to RW.

有办法做到吗?

使用私有继承而不是公共继承。使用using关键字使父类的方法在子类中可用。

公共继承适用于使用父类对象的人也可以使用chid类对象的情况(有关详细信息,请查阅Liskov替换原则)。您的要求打破了这一点,因此不存在公共继承的情况。

听起来class RO有一个不变量:"永远不要修改*p"(即使它在p上偷偷地修改了const_cast)。如果class RW违反了这个不变量,它就不能是class RO的子类。

我猜你真正想要的是更像的东西

class Readable {
public:
    virtual ~Readable();
    virtual void read() const = 0;
};
class RO
  : public Readable {
public:
    void setup(const int* p);
    void read() const;
private:
    const int* m_p;
};
class RW
  : public Readable
{
public:
    void setup(int* p);
    void read() const;
    void write();
private:
    int* m_p;
};

如果接下来的问题是:"DRY呢?现在我必须实现两次read()?",请注意,您可以在基类Readable中定义一个静态成员函数,类似于:

    static void do_read(const int* p);