【问题标题】:Efficient way to bypass Error C2248 "cannot access protected member declared in class"绕过错误 C2248“无法访问在类中声明的受保护成员”的有效方法
【发布时间】:2017-09-21 03:47:10
【问题描述】:

我正在实现一个 c++ 应用程序,除此之外,我还使用 Poco 库。具体来说,我正在尝试使用 poco 日志框架。我创建了一个类,它使用来自 poco 示例之一的以下代码来创建日志记录机制:

 AutoPtr<PatternFormatter> pPatternFormatter(new PatternFormatter());
 AutoPtr<FormattingChannel>pFormattingChannel(new 
 FormattingChannel(pPatternFormatter));

 pPatternFormatter->setProperty("pattern", "%s: %p : %t");

 AutoPtr<ConsoleChannel> pConsoleChannel(new ConsoleChannel());
 pFormattingChannel->setChannel(pConsoleChannel);

但是,当我尝试用 poco SharedPtr 指针替换 poco AutoPtr 我收到以下构建错误:

错误 C2248 'Poco::FileChannel::~FileChannel':无法访问在类 'Poco::FileChannel' 中声明的受保护成员

我已经搜索并发现 FileChannel 类的析构函数受保护,我假设使用它是为了防止通过指向其基的指针删除对象。 使用公共或受保护的访问说明符使我的类派生自 FileChannel 以使 SharedPtr 工作或以其他方式工作是否有效?

【问题讨论】:

    标签: c++ protected derived-class poco-libraries


    【解决方案1】:

    出于好奇,我想:如果派生类将析构函数简单地公开怎么办?实际上,这听起来太容易了,但我相信它应该可以工作。

    样本test-prot-dtor.cc:

    #include <iostream>
    
    class Base {
    
      public:
        Base() { std::cout << "Base::Base()" << std::endl; }
      protected:
        virtual ~Base() { std::cout << "Base::~Base()" << std::endl; }
    };
    
    class Derived: public Base {
    
      public:
        Derived() { std::cout << "Derived::Derived()" << std::endl; }
        virtual ~Derived() { std::cout << "Derived::~Derived()" << std::endl; }
    };
    
    int main()
    {
    #if 0 // Does not work!
      Base *pBase = new Derived;
      delete pBase;
      /* here:
       * error: 'virtual Base::~Base()' is protected
       */
    #endif // 0
      Derived *pDerived = new Derived;
      delete pDerived;
      // done
      return 0;
    }
    

    在 Windows 10(64 位)的 cygwin 中使用 VisualStudio 2013 (Express) 和 gcc 进行测试。下面是与后者的示例会话:

    $ g++ --version
    g++ (GCC) 5.4.0
    
    $ g++ -std=c++11 -c test-prot-dtor.cc
    
    $ ./test-prot-dtor     
    Base::Base()
    Derived::Derived()
    Derived::~Derived()
    Base::~Base()
    
    $
    

    关于你的想法(让SharedPtr 成为你派生类的朋友)我不确定。这取决于SharedPtr 的实现细节,即它是“自己完成工作”还是将其委托给另一个(最终甚至是隐藏的)类/方法或函数......

    【讨论】:

      猜你喜欢
      • 2014-07-06
      • 2014-01-10
      • 2012-11-15
      • 2016-12-02
      • 1970-01-01
      • 2013-07-28
      • 2011-09-06
      • 2015-03-25
      相关资源
      最近更新 更多