私はこの共有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.
~SharedPtr<Foo_impl>
と以外に誰が電話をかけている可能性がFoo
ありFooFactory
ますか?それはどこから来て、どうすれば修正できますか?
注:~Foo
仮想化は役に立ちません。これは私にとってさらに不可解です。
* implが共有されているという事実はここでは関係ありません。私は、典型的な「copy-ctor/assignmentメソッドを定義してください」というコメントを避けたいだけです。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 }
...