开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜