从私有成员类中断封装派生的模板类

Template class derived from private member class breaks encapsulation

本文关键字:派生 封装 成员类 中断      更新时间:2023-10-16

我发现了一种奇怪的方法来打破类派生的类的封装

采取以下措施

class Base
{
private:
class Member
{
public:
virtual ~Member() {}
virtual void Function() = 0;
};
};

如果您尝试从此私有类派生

class DerivedMember : public Base::Member
{
public:
DerivedMember() {}
virtual void Function() {/*Do something*/}
};

您收到编译错误

error: 'class Base::Member' is private
error: within this context

但是,如果您从中派生一个模板

template <typename T>
class TemplateDerivedMember : public Base::Member
{
public:
TemplateDerivedMember () {}
virtual void Function() {/*Do something*/}
};

然后编译器将接受它,并允许这种情况发生。

我已经针对GCC 8.1和GCC 4.6对此进行了测试,并且两者都具有相同的行为。 这是一个错误,还是应该允许的事情?将其派生为模板类是否会隐式地将TemplateDerivedMember类作为Base的成员?(它似乎在全局命名空间中无法访问(

是的,这是一个错误,显然自 GCC 11 以来已修复。据我所知,Clang和MSVC总是拒绝代码。演示:https://gcc.godbolt.org/z/9evfYq5hc