看看代码。我的界面看起来像这样:
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类我可以调用这些私有成员函数?对于任何建议,我将非常感激。
此致 阿图尔
答案 0 :(得分:1)
_&#34;如何使用对Abstract_base类的引用来阻止调用这两个私有成员函数?我只是不希望用户有权访问“Derived_2&#34; ._
中f2()
和Derived_1
中的f1()
通过派生类声明使用范围运算符,无法隐藏这些函数。
&#34;令我惊讶的是为什么使用Handler类我可以调用这些私有成员函数?&#34;
至于你的样品
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; }
};
使用派生类中的public
函数覆盖private
基类函数是完全可以的。
这些函数覆盖仍然可以通过Base
/ Abstract_base
类接口显示。
private
范围说明符使它们无法直接调用客户端。
答案 1 :(得分:1)
您无法使用对Abstract_base
类的引用来阻止调用这两个私有成员函数。当您通过引用或基类的指针访问方法时,将不会考虑派生类的访问权限。 (编译器如何知道?)
根据Liskov替代原则(LSP),
使用指针或对基类的引用的函数必须能够 在不知情的情况下使用派生类的对象。
答案 2 :(得分:0)
你做不到。你不能阻止两件事:
Derived_1 der1;
((Abstract_base*)&der1)->f2 (); // 1
指针或引用转换:
Derived_1 d;
Abstract_base* bp = &d; // 2
Abstract_base& ref = d; // 2
C ++没有提供停止转换到基础指针/引用,或执行对象切片到基础的设置。 C ++都没有规定派生类必须在指定的保护级别中实现虚函数。