【问题标题】:How can I initialize the d (pointer) of the pimple idiom of an static class?如何初始化静态类的疙瘩习语的 d (指针)?
【发布时间】:2011-08-12 05:28:29
【问题描述】:

这是我的标题代码:

#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' 的前向声明

【问题讨论】:

  • 你收到什么信息?
  • 那会是什么?您收到什么错误消息?
  • 您是否在某处定义了 Pimple 类?执行new 时是否可见?
  • 这样使用 CLandTypes::Pimple * d = new CLandTypes::Pimple();
  • 我添加了更多代码和两个错误。

标签: c++ initialization static-class


【解决方案1】:

移动这一行:

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

CLandTypes::Pimple 的类定义之后。

它反对您尝试使用new 创建一个它一无所知的类的实例。

如果您这样做,请在您的 CLandTypes::CLandTypes 构造函数的定义中删除检查 d 是否为 nullptr(又名 !d)的代码。此代码可能导致内存泄漏。此外,在调用 new 然后再抛出 ::std::bad_alloc 后再次检查是完全没有必要的,因为 new 被定义为在分配失败时抛出 ::std::bad_alloc

如果在初始化CLandTypes::d 的静态初始化程序运行之前运行构造函数,则可能发生内存泄漏。只有当CLandTypes 的构造函数在其他地方的静态初始化程序中使用时,才会发生这种情况。将会发生的情况是,构造函数会给 d 一个值,然后 d 的静态初始化程序将在稍后运行并覆盖该值,从而导致内存泄漏。

【讨论】:

  • 是的——我应该做些什么吗? (我不是很了解这个平台)
  • @oRUMOo:投票计数下方应该有一个小复选框(在它们之间有一个上下箭头的地方)。检查它,这将我的答案标记为“已接受”。
【解决方案2】:

尝试将“类 Pimple”声明为公共而不是私有,并尝试让我知道这是否有帮助。 确保在实例化之前定义类。

【讨论】:

  • 公开Pimple类不是一个好主意,因为它破坏了pimple-idiom。
  • @oRUMOo:理论上是这样,实际上你的用户仍然需要在你的头文件中看到名称,所以它也可以是公开的。
  • @oRUMOo:如果您想访问班级以外的班级成员,他们必须是公开的。如果您希望成员是私有的,请使用访问器类型方法通过公共包装函数公开它。如果您想对此 Pimple 进行静态引用,请尝试使用静态容器类对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多