【发布时间】:2016-08-14 18:49:47
【问题描述】:
我试图用我自己的 ptr 来包装 boost 侵入 ptr,这会使转换为 bool 过载。此外,在我的 ptr 中,我想限制对某些 boost 侵入 ptrmethods 的访问。起初我使用 boost intrusive ptr 作为我的 ptr 的私有成员并使用 bool 成语,它运行良好并使用了 bool 成语。 在某些时候,出于我自己的特殊原因,我需要新的 ptr 是 boost 侵入式 ptr 的类型,所以我使用了私有继承,但这不起作用。出于某种原因,gcc 试图将我的 ptr 视为增强侵入 ptr 并拒绝使用公开暴露的 bool 成语。 这是一个演示它的示例代码:
#include <boost/intrusive_ptr.hpp>
#include <stdio.h>
class Object
{
public:
Object() : _refCount(0) {}
void addRef() { _refCount++; }
unsigned int releaseRef() { return --_refCount; }
private:
unsigned int _refCount;
};
inline void intrusive_ptr_release(Object* p)
{
if (p->releaseRef() == 0)
{
delete p;
}
}
inline void intrusive_ptr_add_ref(Object* p)
{
p->addRef();
}
// Option A: using private member
template<class ObjectT>
class PtrA
{
public:
explicit PtrA(ObjectT* obj) : _obj(obj) {}
PtrA() {}
ObjectT* operator->() { return _obj.operator->(); }
const ObjectT* operator->() const { return _obj.operator->(); }
ObjectT* get() { return _obj.get(); }
const ObjectT* get() const { return _obj.get(); }
typedef const ObjectT* (PtrA::*unspecified_bool_type)() const;
operator unspecified_bool_type() const
{
if (_obj != NULL)
{
printf("ptr is not null\n");
}
return _obj.get() == 0 ? 0: (unspecified_bool_type)&PtrA::get;
}
private:
boost::intrusive_ptr<ObjectT> _obj;
};
// Option B: using private inheritance
template<class ObjectT>
class PtrB : private boost::intrusive_ptr<ObjectT>
{
public:
explicit PtrB(ObjectT* obj) : boost::intrusive_ptr<ObjectT>(obj) {}
PtrB() {}
using boost::intrusive_ptr<ObjectT>::operator->;
using boost::intrusive_ptr<ObjectT>::get;
typedef const ObjectT* (PtrB::*unspecified_bool_type)() const;
operator unspecified_bool_type() const
{
const ObjectT* p = boost::intrusive_ptr<ObjectT>::get();
if (p != NULL)
{
printf("ptr is not null\n");
}
return p == 0 ? 0 : (unspecified_bool_type)&PtrB::get;
}
};
int main()
{
// this verison compiles
// PtrA<Object> obj(new Object());
PtrB<Object> obj(new Object());
if (obj == NULL)
{
printf("object is null\n");
}
if (!obj)
{
printf("object is null\n");
}
return 0;
}
在此代码中使用 PtrB 会导致编译错误:
g++ -std=c++11 ./test.cpp
...
./test.cpp: In function 'int main()':
./test.cpp:88:16: error: 'boost::intrusive_ptr<Object>' is an inaccessible base of 'PtrB<Object>'
if (obj == NULL)
^
In file included from /usr/include/boost/smart_ptr/intrusive_ptr.hpp:167:0,
from /usr/include/boost/intrusive_ptr.hpp:16,
from ./test.cpp:1:
/usr/include/boost/smart_ptr/detail/operator_bool.hpp:60:10: error: 'bool boost::intrusive_ptr<T>::operator!() const [with T = Object]' is inaccessible
bool operator! () const BOOST_NOEXCEPT
^
./test.cpp:92:10: error: within this context
if (!obj)
^
./test.cpp:92:10: error: 'boost::intrusive_ptr<Object>' is not an accessible base of 'PtrB<Object>'
如果 boost intrusive ptr 是私有继承的,那么 GCC 会尝试使用什么来代替 public bool 习惯用法? 我使用 gcc 4.8.5
【问题讨论】:
-
@WhiZTiM 我修复了 OP 的示例 - 您只需更改注释的行。
-
@Barry,哦……瞎了我……是的……转载。您的回答说明了这一点。 :-)
标签: c++ inheritance gcc