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.

除了and~SharedPtr<Foo_impl>之外,还有谁可能在打电话?这是从哪里来的,我该如何解决?FooFooFactory

注意:制作~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         }
 ...
4

1 回答 1

2

您没有声明赋值运算符,Foo因此如果您使用它,编译器将为您定义一个。编译器生成的将使用 then 复制赋值运算符,SharedPtr其中通过许多中间函数调用deletea Foo_impl

我看不到你的Bar.cpp,所以我不能说你可能在哪里复制Foo.

于 2012-06-29T20:18:43.507 回答