我有这个共享的 pimpl*。它向前声明了实现对象,并有一个自定义实现的共享指针对象来实现 pimpl 习惯用法(同样,具有共享语义)。浓缩,它看起来像这样:
Foo.h
#include "SharedPtr.h"
class Foo_impl;
class FooFactory;
class Foo {
friend class FooFactory;
private:
SharedPtr<Foo_impl> pimpl;
Foo(SharedPtr<Foo_impl>);
public:
~Foo();
};
struct FooFactory {
Foo build() const;
};
Foo.cpp
#include "Foo.h"
Foo FooFactory::build() const {
return Foo(SharedPtr<Foo_impl>(new Foo_impl(/*...*/)));
}
Foo::Foo(SharedPtr<Foo_impl> pimpl)
: pimpl(pimpl) {
}
Foo::~Foo() {
}
现在,(我认为)编译器在编译Bar.cpp
(使用Foo
对象和其他 SharedPtr
对象)时变得非常聪明并抱怨:
SharedPtr.h: In member function ‘void Deallocator<T>::operator()(T*) const [with T = Foo_impl]’:
SharedPtr.h:54: instantiated from ‘void SharedPtr<T, Delete>::drop() [with T = Foo_impl, Delete = Deallocator<Foo_impl>]’
SharedPtr.h:68: instantiated from ‘SharedPtr<T, Delete>::~SharedPtr() [with T = Foo_impl, Delete = Deallocator<Foo_impl>]’
SharedPtr.h:44: warning: possible problem detected in invocation of delete operator:
SharedPtr.h:42: warning: ‘t’ has incomplete type
Foo.h:29: warning: forward declaration of ‘struct Foo_impl’
SharedPtr.h:44: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
除了and~SharedPtr<Foo_impl>
之外,还有谁可能在打电话?这是从哪里来的,我该如何解决?Foo
FooFactory
注意:制作~Foo
虚拟并没有帮助,这对我来说更令人费解。
* impl 被共享的事实在这里无关紧要,我只是想阻止典型的“请定义一个复制-ctor/分配方法”的评论。共享 pimpl 指针是完全有意的。
编辑:SharedPtr
界面:
33 template <typename T> struct Deallocator {
34 private:
35 bool doDelete; // not const to be def. assignable
36 public:
38 Deallocator(bool doDelete = true) : doDelete(doDelete) {}
39 bool willDelete() const {
40 return doDelete;
41 }
42 void operator()(T* t) const {
43 if (doDelete)
44 delete t;
45 }
46 };
47
48 template <typename T, typename Delete = Deallocator<T> > class SharedPtr : private SharedPtrBase {
49 private:
50 Delete del;
51 T* ptr;
52 void drop() {
53 if (ptr && shouldDelete()) {
54 del(ptr);
55 }
56 ptr = NULL;
57 leave();
58 }
59 public:
60 // SharedPtr(p,false) will not delete the pointer! Useful for Stackobjects!
61 explicit SharedPtr(T* ptr = NULL, Delete del = Delete())
62 : SharedPtrBase(), del(del), ptr(ptr) {
63 }
64 SharedPtr(SharedPtr const& from)
65 : SharedPtrBase(from), del(from.del), ptr(from.ptr) {
66 }
67 ~SharedPtr() {
68 drop();
69 }
70 SharedPtr& operator=(SharedPtr const& from) {
71 if (&from != this) {
72 drop();
73 del = from.del;
74 ptr = from.ptr;
75 join(&from);
76 }
77 return *this;
78 }
79 SharedPtr& operator=(T* from) {
80 return *this = SharedPtr(from,del);
81 }
...