绕过错误 C2248 的有效方法 "cannot access protected member declared in class"
Efficient way to bypass Error C2248 "cannot access protected member declared in class"
我正在实现一个 C++ 应用程序,除此之外我还使用 Poco 库。具体来说,我正在尝试使用 poco 日志记录框架。我创建了一个 class,它使用来自 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': 无法访问在 class 'Poco::FileChannel'
中声明的受保护成员
我搜索并发现 FileChannel class 的析构函数受到保护,我认为使用它是为了防止通过指向其基址的指针删除对象。
使我的 class 派生自具有 public 的 FileChannel 或受保护的访问说明符以使 SharedPtr 工作或以其他方式工作是否有效?
出于好奇,我想:如果派生class使析构函数简单地public呢?实际上,这听起来太简单了,但我相信它应该可行。
样本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 位)上使用 VisualStudio 2013 (Express) 和 cygwin 中的 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
成为你派生 class 的朋友)我不确定。这取决于 SharedPtr
的实现细节,即它是 "does the work itself" 还是将其委托给另一个(最终甚至隐藏)class/method 或函数...
我正在实现一个 C++ 应用程序,除此之外我还使用 Poco 库。具体来说,我正在尝试使用 poco 日志记录框架。我创建了一个 class,它使用来自 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': 无法访问在 class 'Poco::FileChannel'
中声明的受保护成员我搜索并发现 FileChannel class 的析构函数受到保护,我认为使用它是为了防止通过指向其基址的指针删除对象。 使我的 class 派生自具有 public 的 FileChannel 或受保护的访问说明符以使 SharedPtr 工作或以其他方式工作是否有效?
出于好奇,我想:如果派生class使析构函数简单地public呢?实际上,这听起来太简单了,但我相信它应该可行。
样本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 位)上使用 VisualStudio 2013 (Express) 和 cygwin 中的 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
成为你派生 class 的朋友)我不确定。这取决于 SharedPtr
的实现细节,即它是 "does the work itself" 还是将其委托给另一个(最终甚至隐藏)class/method 或函数...