繁体   English   中英

使用对基类的引用访问派生类的私有成员函数

[英]Access to private member functions of derived class using reference to a base class

看看代码。 我有这样的界面:

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

        virtual void f1 () = 0;
        virtual void f2 () = 0;
};

基类看起来像这样:

class Base : public Abstract_base {
    public:
        virtual ~Base() {}

        virtual void f1 () override { cout << "f1" << endl; }
        virtual void f2 () override { cout << "f2" << endl; }
};

我有两个派生类,像这样:

class Derived_1 : public Base {
    public:
        virtual ~Derived_1() {}

    private:
        virtual void f2 () override { cout << "Derived_1::f2 ()" << endl; }

};

class Derived_2 : public Base {
    public:
        virtual ~Derived_2() {}

    private:
        virtual void f1 () override { cout << "Derived_2::f1 ()" << endl; }
};

最后我有Handler类,看起来像这样:

class Handler {
    public:
        Handler (Abstract_base& b) : base (b) {}
        virtual ~Handler() {}

        void process_1 () { 
            base.f1 ();
        }

        void process_2 () { 
            base.f2 ();
        }

    private:
        Abstract_base& base;
};

而main.cpp看起来像这样:

int main (int argc, char** argv) {

    Derived_1 der1;
    der1.f2 ();

    Derived_2 der2;
    der2.f1 ();

    Handler handler1 (der1);
    handler1.process_2 ();

    Handler handler2 (der2);
    handler2.process_1 ();

    return 0;
}

当然代码不会编译,因为der1.f2()和der2.f1()是私有的,但如果我注释掉这两条指令并保留handler1.process_2()和handler2.process_1()指令,代码将编译并生成输出:

Derived_1::f2 ()
Derived_2::f1 ()

题:

如何使用对Abstract_base类的引用来阻止调用这两个私有成员函数? 我只是不希望用户有权访问Derived_1中的f2()和Derived_2中的f1()。

据我所知,我无法对Derived_1 :: f2()和Derived_2 :: f1()使用delete关键字。

你能建议我解决这个问题吗?

我知道其中一个解决方案可能是使Handler成为这样的模板类:

template <class B>
class Handler_templ {
    public:
        Handler_templ (B& b) : base (b) { }
        virtual ~Handler_templ() {}

        void process_1 () { 
            base.f1 ();
        }

        void process_2 () { 
            base.f2 ();
        }

    private:
        B& base;
};

并像这样使用它:

Handler_templ<Derived_1> h1 (der1);
Handler_templ<Derived_2> h2 (der2);

h1.process_2 ();
h2.process_1 ();

让我感到惊讶的是为什么使用Handler类我可以调用这些私有成员函数? 对于任何建议,我将非常感激。

真诚的,阿图尔

_“如何使用对Abstract_base类的引用来阻止调用这两个私有成员函数?我只是不希望用户有权访问Derived_1f2()和`Derived_2”中的f1()

通过派生类声明使用范围运算符无法隐藏这些函数。

“令我惊讶的是为什么使用Handler类我可以调用这些私有成员函数?”

至于你的样品

class Base : public Abstract_base {
public:
    virtual ~Base() {}
    virtual void f1 () override { cout << "f1" << endl; }
    virtual void f2 () override { cout << "f2" << endl; }
};

class Derived_1 : public Base {
public:
    virtual ~Derived_1() {}
private:
    virtual void f2 () override { cout << "Derived_1::f2 ()" << endl; }
};

class Derived_2 : public Base {
public:
    virtual ~Derived_2() {}
private:
    virtual void f1 () override { cout << "Derived_2::f1 ()" << endl; }
};

使用派生类中的private函数来覆盖public基类函数是完全可以的。
这些函数覆盖仍然可以通过Base / Abstract_base类接口看到。

private范围说明符使它们无法直接调用客户端。

您无法阻止使用对Abstract_base类的引用来调用这两个私有成员函数。 当您通过引用或基类的指针访问方法时,将不会考虑派生类的访问权限。 (编译器如何知道?)

根据利斯科夫替代原则(LSP),

使用指针或对基类的引用的函数必须能够在不知道它的情况下使用派生类的对象。

你不能这样做。 你不能阻止两件事:

Derived_1 der1;
((Abstract_base*)&der1)->f2 ();  // 1

和指针或引用转换:

Derived_1 d;

Abstract_base* bp = &d; // 2
Abstract_base& ref = d; // 2

C ++没有提供停止转换基指针/引用,或执行对象切片到基础的规定。 C ++都没有要求派生类必须在指定的保护级别实现虚函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM