我的朋友给我看了以下代码
struct A {
virtual void f() = 0;
virtual void g() = 0;
};
struct AInternal : A {
virtual void f() { /* ... */ }
virtual void g() { /* ... */ }
};
他正在使用AInternal
作为实现最多的内部类(如果不是全部A
)。然后他继承自AInternal
,但由于他希望AInternal
无法访问(因为它是一个实现细节),所以他继承了protected(以其实现)。他还做了using
基类名称使A
可访问(默认情况下受保护,因为AInternal
也被继承保护)
struct C : protected AInternal {
using AInternal::A;
};
实际上,这很好(但是我们后来发现,它仍然保留了成员函数private
- 只是基类被创建public
),但它只适用于GCC。它无法使基本A
可访问。任何的想法?我们甚至可以让它破坏适用于Clang的代码
struct C : public AInternal {
protected:
using AInternal::A;
};
C *c = 0;
A *a = c; // error on GCC!
有人可以帮忙吗?
答案 0 :(得分:5)
您只影响inject-class-name的可见性。不应影响基础子对象或其成员的访问保护。如果Clang或GCC允许它影响基础内的演员有效性或访问权,那就是他们的错误。
[class.member.lookup] 10.2 / 3说
在声明集中,using声明被它们指定的成员替换,类型声明(包括inject-class-names)被它们指定的类型替换。
基类子对象在成员查找中没有名称;注入类名称。