1

私はこの共有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         }
 ...
4

1 に答える 1

2

の代入演算子は宣言しないFooので、それを使用すると、コンパイラが代入演算子を定義します。コンパイラが生成したものは、コピー代入演算子を使用します。この演算子はSharedPtr、いくつかの中間関数を介して、を呼び出しdeleteますFoo_impl

あなたが見えないBar.cppので、どこにコピーしているのかわかりませんFoo

于 2012-06-29T20:18:43.507 に答える