Как я могу инициализировать d (указатель) идиомы прыщ статического класса? - PullRequest
0 голосов
/ 25 апреля 2011

Вот мой код заголовка:

#ifndef CLANDTYPES_H
#define CLANDTYPES_H

class CLandTypes
{
public:
    CLandTypes();
    ~CLandTypes();
private:
    class Pimple;
    static Pimple * d;
};

#endif // CLANDTYPES_H

, потому что это должен быть статический класс, который я пытался кодировать в своем файле cpp:

#include "clandtypes.h"

CLandTypes::Pimple * CLandTypes::d = new CLandTypes::Pimple();
...

Но что-то не так!

---------- РЕДАКТИРОВАТЬ ----------

вот мой расширенный код C ++:

#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;
    }
}

две мои ошибкиявляются:

недопустимое использование неполного типа 'struct CLandTypes :: Pimple'
прямое объявление 'struct CLandTypes :: Pimple'

Ответы [ 2 ]

1 голос
/ 25 апреля 2011

Переместите эту строку:

CLandTypes::Pimple * CLandTypes::d = new CLandTypes::Pimple();

, чтобы быть после определения класса для CLandTypes::Pimple.

Она возражает против вашей попытки использовать new для создания экземпляра классаон ничего не знает.

Если вы сделаете это, удалите код, который проверяет, является ли d nullptr (он же !d) в вашем определении конструктора CLandTypes::CLandTypes.Этот код может привести к утечке памяти.Кроме того, повторная проверка после вызова new и последующего выброса ::std::bad_alloc совершенно не нужна, поскольку new определено для выброса ::std::bad_alloc при ошибке выделения.

Способ возникновения утечки памятиесли конструктор запускается до запуска статического инициализатора, который инициализирует CLandTypes::d.И это может произойти, только если конструктор для CLandTypes используется в статическом инициализаторе где-то еще.Что произойдет, так это то, что конструктор даст значение d, а затем статический инициализатор для d запустится через некоторое время и перезапишет это значение, что приведет к утечке памяти.

0 голосов
/ 25 апреля 2011

Попробуйте объявить "класс Pimple" общедоступным, а не частным, и попробуйте и дайте мне знать, если это поможет.Убедитесь, что вы определили класс перед его созданием.

...