【问题标题】:Setting private member pointer to the same class as NULL?将私有成员指针设置为与NULL相同的类?
【发布时间】:2014-10-01 15:17:43
【问题描述】:

我在一个 C++ 库中遇到了以下结构:

在 myClass.h 中

class myClass {
public:
static myClass* Instance();
.
.
private:
static myClass* _instance;
.
.
};

在 myClass.cpp 中

myClass* myClass::_instance = NULL;

// followed by the all other functions..

myClass::myClass() {
    .
    .
}

myClass* myClass::Instance() {
    if (_instance == NULL) {
        .
        .
    }
    .
    .
}

那么在任何函数之外将 _instance 设为 NULL 指针有什么用呢?这行代码什么时候执行?

谢谢。

编辑: 添加主函数。 myClass.cpp 中的实例函数检查指针的值。仍然不明白指针何时设置为 NULL。

int _tmain(int argc, T_CHAR* argv[]) {

myClass* instance = myClass::Instance();

.
.
.

return 0;
}

【问题讨论】:

  • @PaulR 什么?怎么是复制品?仅仅因为这两个问题都涉及静态成员并不能神奇地使它们完全相同。
  • @LightnessRacesinOrbit:在完全改变问题性质的后续编辑之前查看问题的原始版本。
  • @PaulR:我没有看到任何与您确定的问题重复的修订。
  • @LightnessRacesinOrbit:好吧,除非我无意中链接到错误的问题,他们都是关于将私有静态变量初始化为 0 以及为什么要这样做。
  • @PaulR:不,一个是如何做到这一点。另一个是为什么要这样做。

标签: c++


【解决方案1】:

那么在任何函数之外将_instance 设为NULL 指针有什么用?

静态数据成员通常必须在包含它们的类的命名空间中定义,在一个源文件中;它们受单一定义规则的约束,因此在任何使用它们的程序中都必须有一个定义。就是这个定义。

使用NULL 对其进行初始化确保它最初为空,以便Instance() 函数可以确定该实例是否已创建。这并不是绝对必要的,因为与所有静态变量一样,无论您是否显式提供初始化程序,它都会被零初始化。

这行代码什么时候执行?

静态初始化期间,在程序中的任何其他代码之前;因为它是一个带有常量初始化器的普通类型。

【讨论】:

    【解决方案2】:

    我曾经偶然发现过这样的事情。这类似于单例。原因(正如执行此操作的人所解释的那样)是他特别想在第一次 getInstance() 函数调用时初始化实例,并且他想确保 ​​_instance 指针首先被初始化为 NULL (而不是来自一些垃圾内存)以便检查

    if (_instance == NULL)
    

    在函数中正常工作。

    我不确定这里是否是这种情况,但有可能。

    【讨论】:

    • 是的,就是这样。谢谢你。我想知道那一行代码什么时候执行,因为它不是构造函数或任何其他函数的一部分?
    • “类似于单例。” 不只是“类似于”..!
    • @pract:不在您向我们展示的代码中。可能在myClass的一些静态成员函数中。
    • @pract myClass::_instance 初始化的代码行在使用它的代码可以执行之前执行,即在初始化期间。有关详细信息,请参阅this question 的答案。
    【解决方案3】:
    myClass* myClass::_instance = NULL;
    

    代码尝试初始化静态成员变量。

    【讨论】:

      【解决方案4】:

      这是一个初始化,确保指针从程序一开始就以值NULL 开始生命。1

      它给指针一个无效的,但可识别可测试值,然后在程序中稍后将一些有用的指针值分配给它。这样,您可以安全地测试指针以查看它是否已被赋予所述有用值。

      在这种情况下,由于您显示的是单例,因此“稍后”表示“当首次请求 myClass 的实例时”使用您未显示的一些 myClass::getInstancePlease() 函数。

      使用函数-static 实例而不是类-static 指向某个[可能是动态分配的]实例的指针来实现单例更为常见。

      1 作为具有静态存储时长的对象,它无论如何都会这样做;因此,除了记录程序员的意图之外,这种初始化实际上完全没有意义。

      【讨论】:

      • 恐怕你的脚注不正确。如果你不初始化一个静态数据成员,它不会默认为 0。它根本不存在,当你尝试访问它时你会得到一个链接时错误。
      • @5gon12eder:That's total nonsense。你是从哪里听来的?! You're confusing initialisation for definition。事实上,作为程序启动的第一步,所有静态存储持续时间对象都肯定会被初始化为零。
      • 你是对的,说“如果你不定义”它是正确的。我想说的是,如果你从代码中删除混淆 OP 的行,它会给你一个链接器错误。因此,这条线并非完全没有意义。写int * Test::pointer; 而不是int * Test::pointer = 0; 确实会有同样的效果。
      • @5gon12eder:对,我的脚注就是这么说的!
      • 是的,但我很确定这需要对语言的细微差别有一定程度的理解,这超出了人们提出此类问题的预期。
      【解决方案5】:

      静态关键字意味着它被类实例化的所有对象共享。因此,您需要在任何函数之外对其进行初始化。静态声明它是在类的所有实例之间共享的类变量。它与实例变量相反,每个实例都有自己的副本。要访问类变量,有两种方法。 1) a_class::static_variable 2) a_class a; a.static_variable。初始化必须在源文件 (.cpp) 中而不是在头文件中。 因为它是一个静态变量,编译器只需要创建它的一个副本。如果不这样做,则会出现链接错误。如果它在头文件中,您将在包含头文件的每个文件中获得一个副本,因此从链接器获取多重定义的符号错误。

      静态数据成员不是给定类类型对象的一部分;它们是单独的对象。因此,静态数据成员的声明不被视为定义。数据成员在类范围内声明,但在文件范围内执行定义。

      【讨论】:

      • 我没看到你在哪里回答这个问题。
      猜你喜欢
      • 2010-12-14
      • 2020-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多