5

我的朋友向我展示了以下代码

struct A {
  virtual void f() = 0;
  virtual void g() = 0;
};

struct AInternal : A {
  virtual void f() { /* ... */ }
  virtual void g() { /* ... */ }
};

AInternal用作实现大多数(如果不是全部A)的内部类。然后他继承自AInternal,但由于他希望它AInternal保持不可访问(因为它是一个实现细节),他继承了 protected (根据实现)。他还做的是usinging 基类名称以使其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!

有人可以帮忙吗?

4

1 回答 1

5

您只会影响注入类名的可见性。基础子对象或其成员的访问保护不应受到影响。如果 Clang 或 GCC 允许它影响基础内的强制转换有效性或访问,那是他们的错误。

[class.member.lookup] 10.2/3 说

在声明集中,使用声明被它们指定的成员替换,类型声明(包括注入类名)被它们指定的类型替换。

基类子对象在成员查找中没有名称;注入的类名确实如此。

于 2013-07-15T03:11:15.153 回答