我似乎无法使用基类作为函数参数,我是否搞砸了我的继承?
我的主要内容如下:
int some_ftn(Foo *f) { /* some code */ };
Bar b;
some_ftn(&b);
Run Code Online (Sandbox Code Playgroud)
并且以这种方式继承自Foo的类Bar:
class Bar : Foo
{
public:
Bar();
//snip
private:
//snip
};
Run Code Online (Sandbox Code Playgroud)
这应该不起作用吗?我似乎无法在我的主要功能中进行该调用
$ cat inheritance.cpp
#include <iostream>
using namespace std;
class A { };
class B : private A { };
int main() {
A* ab = new B;
}
$
$ g++ inheritance.cpp
inheritance.cpp: In function 'int main()':
inheritance.cpp:9: error: 'A' is an inaccessible base of 'B'
$
Run Code Online (Sandbox Code Playgroud)
我只是不明白这个错误.
据我所知,正如本教程所证实的那样,private继承只应改变class B外部世界可见成员的方式.
我认为私有说明者所做的不仅仅是改变class B成员的可见性.
这个问题的背景是基于一个实际的示例,我想从一对用于管理对共享资源的读/写锁定访问的类中删除«friend»依赖项.
这是该场景的原始结构设计的抽象:

标记为红色,我想从设计中删除这个丑陋的"朋友"依赖.
简而言之,为什么我在那里有这个东西:
ClassAProvider共享对ClassA多个并发访问Client实例的引用Client实例应该ClassA只通过ClassAAccessor管理内部的辅助类来访问ClassA将所有打算使用的方法隐藏起来ClassAAccessor.ClassA可以确保Client需要使用ClassAAccessor实例ClassA如果Client操作失败(因为例如未捕获的异常),则该模式主要用于确保将实例保留在已定义的状态.考虑
ClassA提供(内部可见的)配对操作,如lock()/ unlock()或open()/ close().
在任何情况下都应调用(state-)反转操作,尤其是当客户端由于异常而崩溃时.
这可以通过ClassAAcessor生命周期行为安全地处理,析构函数实现可以确保它.以下序列图说明了预期的行为:

此外,只需使用C++范围块,Client实例就可以ClassA轻松实现对访问的精确控制:
// ...
{
ClassAAccessor acc(provider.getClassA());
acc.lock();
// do something exception prone ...
} // safely unlock() ClassA
// ...
Run Code Online (Sandbox Code Playgroud)
到目前为止一切都很好,但由于一些很好的理由ClassA,ClassAAccessor应该删除之间的"朋友"依赖关系
The following table lists …为什么调用f不解析第一个函数重载?我收到错误:
source.cpp: In function 'int main()':
source.cpp:12:31: error: 'A' is an inaccessible base of 'B'
class A {}; class B : A {};
void f(const A &) { std::cout << "const A &"; }
template <typename T> void f(T) { std::cout << "Generic"; }
int main() {
B b;
f(dynamic_cast<const A &>(b));
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果我取出dynamic_cast代码将工作,第二个 f被调用(它打印"通用").但我要做的就是第一次打电话.我认为它dynamic_cast会工作,但由于某种原因它会导致问题.我在这做错了什么?