Can a Pointer template class have a virtual destructor?

I came across an amazing revelation when implementing the pimpl idiom with the home class of pointers (I know: why roll on my own, but carry with me). The following three files contain a minimal example:

Pointer.h:

#pragma once 

template <typename T>
class Pointer
{
public:
    Pointer(T*p=0)
        : _p(p)
    {
    }
    virtual ~Pointer()
    {
        delete _p;
    }
private:
    void operator=(const Pointer&);
    Pointer(const Pointer&);

private:
    T*_p;
};

foo.h:

#pragma once
#include "Pointer.h"

struct Foo
{
    Foo();
    ~Foo();

private:
    void operator=(const Foo&);
    Foo(const Foo&);

private:
    Pointer<struct FooPrivate> p;
};

main.cpp:

#include "Foo.h"

int main(int argc, char* argv[])
{
    Foo foo;
    return 0;
}

Do not pay attention to how the insides look Foo.cpp. When I compile main.cppwith MSVC 2008, I get a warning:

pointer.h(13) : warning C4150: deletion of pointer to incomplete type 'FooPrivate'; no destructor called

A warning can be avoided by removing the virtual keyword from the pointer destructor.

That makes no sense to me. Is this warning legal, or is it an error in the MSVC compiler? If so, can I safely ignore the warning?

, , , . .

+5
4

virtual , ; ~Foo, FooPrivate. Pointer<FooPrivate> , , , , , .

virtual Pointer<FooPrivate> -, FooPrivate . , , . , , .

+4

Foo, .

, [foo.cpp]:

#include "foo.h"
#include <iostream>
using namespace std;

struct FooPrivate
{
    FooPrivate() { cout << "FooPrivate::<init>" << endl; }
    ~FooPrivate() { cout << "FooPrivate::<destroy>" << endl; }
};

Foo::Foo()
    : p( new FooPrivate )
{
    cout << "Foo::<init>" << endl;
}

Foo::~Foo()
{
    cout << "Foo::<destroy>" << endl;
}

( Visual ++ 10.0), ,

FooPrivate:: < & INIT GT;
Foo:: < & INIT GT;
Foo:: < >
FooPrivate:: < >

, , , & hellip;

hth.,

+2

delete - Undefined .

0

FooPrivate, , vtable. , , .

0

All Articles