Why am I getting the error “A is an inaccessible b

2020-07-17 06:26发布

Why is the call to f not resolving to the first function overload? I get the error:

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));

}

Note that if I take out the dynamic_cast the code will work yet the second f is called (it prints "Generic"). But what I'm trying to do is to get the first call. I figured a dynamic_cast would work, but for some reason it causes problems. What am I doing wrong here?

标签: c++
4条回答
Fickle 薄情
2楼-- · 2020-07-17 06:30

The default class inheritance is private (class B : A {}; defaults to class B : private A {};).

So you can't handle b through type A.

EDIT: Like Rob said :), the way to fix it is by using public inheritance:

class B : public A {};

EDIT:
The relationship between a publicly derived class and its base class is "is a", meaning that it is a specialization of a more generic type, and as such, it implements the behavior of that generic class and possibly more.

The relationship between a privately derived class and its base class is "implemented in terms of". It prevents objects from being considered extensions of the base class. A good example of its use is boost::noncopyable that prevents objects of a privately derived class from being copied. http://www.boost.org/doc/libs/1_52_0/libs/utility/utility.htm#Class_noncopyable

In the hypothetical case that the requirements include private inheritance and at some point a function is created that wants to reference the object as its base, a public method returning a casted to base class pointer this will do it much like a traditional get() accesses a private data member maintaining the original purpose.

public:
    A *getBase() { return static_cast<A *>(this); }

And then accessed like this:

f(b.getBase());
查看更多
混吃等死
3楼-- · 2020-07-17 06:33

There's nothing special about dynamic_cast when it comes to upcasts. dynamic_cast is equivalent to static_cast in such cases. It is performed at compile-time if the base exists, is unambiguous and is accessible. It fails to compile otherwise.

This is exactly what happens in your case. The base is inaccessible (as the compiler told you already) so the cast fails to compile.

Without the cast the first function is excluded from the overload resolution candidate list (since the base is inaccessible), and the second one wins.

In fact, you don't really need any cast to perform legal upcasts in overwhelming majority of cases. As for illegal upcasts, no C++ cast will help you with that (the only cast that can "break through" private inheritance is C-style cast.)

查看更多
一纸荒年 Trace。
4楼-- · 2020-07-17 06:40

A is a private base of B, so there are very few places where an object of type B can be treated as an A&. If you change the inheritance to public the cast will work, and select the non-template version of f. But dynamic_cast is overkill; every object of type B is an object of type A, so you can use static_cast to disambiguate the call.

查看更多
兄弟一词,经得起流年.
5楼-- · 2020-07-17 06:45

It will fail because of the private inheritance, as mentioned, and because b is passed as an object. dynamic_cast will only work for pointers and references.

See: http://www.cplusplus.com/doc/tutorial/typecasting/

查看更多
登录 后发表回答