How can I initialize the d (pointer) of the pimple idiom of an static class?
Here is my header code:
#ifndef CLANDTYPES_H
#define CLANDTYPES_H
class CLandTypes
{
public:
CLandTypes();
~CLandTypes();
private:
class Pimple;
static Pimple * d;
};
#endif // CLANDTYPES_H
because it should be a static class I tryed to code in my cpp file:
#include "clandtypes.h"
CLandTypes::Pimple * CLandTypes::d = new CLandTypes::Pimple();
...
But something is wrong!
---------- EDIT -------开发者_Go百科---
here is my extended c++ code:
#include "clandtypes.h"
#include "qvector.h"
#include "qpair.h"
CLandTypes::Pimple * CLandTypes::d = new CLandTypes::Pimple();
class CLandTypes::Pimple
{
public:
Pimple();
~Pimple();
QVector > LandTypes;
};
CLandTypes::Pimple::Pimple()
: LandTypes(NULL)
{
LandTypes.push_back(qMakePair((unsigned int) 0, (QString)"undefined"));
LandTypes.push_back(qMakePair((unsigned int) 1, (QString)"rocky"));
}
CLandTypes::Pimple::~Pimple(){}
CLandTypes::CLandTypes()
{
if (!d)
{
d = new Pimple();
if (!d)
{
throw std::bad_alloc();
}
}
}
CLandTypes::~CLandTypes()
{
if(d)
{
delete d;
d = NULL;
}
}
my two errors are:
invalid use of incomplete type 'struct CLandTypes::Pimple'
forward declaration of 'struct CLandTypes::Pimple'Move this line:
CLandTypes::Pimple * CLandTypes::d = new CLandTypes::Pimple();
to be after the class definition for CLandTypes::Pimple
.
It's objecting to your attempt to use new
to create an instance of a class it knows nothing about.
If you do this, remove the code that checks to see if d is nullptr
(aka !d
) in your definition of the CLandTypes::CLandTypes
constructor. This code can result in a memory leak. Also, checking again after you've called new
and then throwing ::std::bad_alloc
is totally unnecessary as new
is defined to throw ::std::bad_alloc
on an allocation failure.
The way the memory leak can occur is if the constructor is run before the static initializer that initializes CLandTypes::d
is run. And that can only happen if the constructor for CLandTypes
is used in a static initializer someplace else. What will happen is that the constructor will give a value to d
and then the static initializer for d
will run sometime later and overwrite that value, thereby causing a memory leak.
Try declaring "class Pimple" as public rather than private and try and let me know if that helps. Make sure you define the class before instantiating it.
精彩评论