首页 > 解决方案 > 从私有成员类派生的模板类打破了封装

问题描述

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

采取以下

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?(它似乎无法在全局命名空间中访问)

标签: c++templatesgcc

解决方案


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


推荐阅读