2

采用以下结构和类:

struct TestStruct
{
};

class TestClass
{
public:
    TestStruct* testStruct;
};

在 中执行以下操作main

TestClass testClass;
if (testClass.testStruct == NULL)
    cout << "It is NULL." << endl;
else
    cout << "It is NOT NULL.";

输出将是:It is NOT NULL.

但是,如果我改为这样做:

TestClass testClass;
if (testClass.testStruct == NULL)
    cout << "It is NULL." << endl;
else
    cout << "It is NOT NULL." << endl << testClass.testStruct;

输出将是:It is NULL.

有趣的是,如果我这样做(与上述基本相同):

TestClass testClass;
if (testClass.testStruct == NULL)
{
    cout << "It is NULL." << endl;
}
else
{
    cout << "It is NOT NULL." << endl;
    cout << testClass.testStruct;
}

输出将是:

It is NOT NULL.
0x7fffee043580.

到底是怎么回事?

4

5 回答 5

13

声明时指针未初始化testClass。您在这里体验到未定义的行为。指针的值将是包含在存储它的内存部分中的最后一个值。

如果您希望它始终NULL,则需要在类的构造函数中对其进行初始化。

class TestClass
{
public:
    TestClass(): testStruct(NULL) {}
    TestStruct* testStruct;
};
于 2013-08-15T18:02:20.750 回答
4

回答

对我来说,它在两个问题中都显示“It is NOT NULL” ,有时您可能会将其视为 NULL

发生上述情况的原因是 C++ 不会自动将任何内容分配给变量,因此它包含未知值

所以未知值有时可能是NULL,但有时可能不是

测试这个理论的最好方法是在 Visual C++ 和 g++ 以及任何其他 c++ 编译器中尝试它

您获得 null 或不为 null 的另一个原因是,当您以不同方式编译应用程序时,编译器会输出不同的可执行文件,因此在一个未定义的变量场景中,编译器可能会输出一个可执行文件,该可执行文件在执行时可能会将未定义的变量指向 NULL或非空

使用 GNU C++ 编译器和 Microsoft 命令行编译器的测试

警告不要使用此代码它很糟糕(这是对两个编译器中未定义变量场景的测试)

代码(基于OP):

#include <iostream>
using namespace std;

struct TestStruct
{
};

class TestClass
{
public:
    TestStruct* testStruct;


};

int main(){
    TestClass testClass;
    if (testClass.testStruct == NULL)
        cout << "It is NULL." << endl;
    else
        cout << "It is NOT NULL." << endl << testClass.testStruct;
}

GNU G++ GNU G++ 测试

视觉工作室 CL

CL

于 2013-08-15T18:13:51.213 回答
3

有时为 NULL ,testStruct有时不为 NULL。

确保您的构造函数清除指针。C++ 中的变量不默认为 NULL/0。

于 2013-08-15T18:00:39.697 回答
2

好吧,默认情况下指针不会被初始化。您必须在构造函数中执行此操作。它只包含 RAM 中的内容。在通常的 32 位系统上,它为 NULL 的可能性约为 0,2e-9。在 64 位系统(在 64 位程序集中)它会更低。

于 2013-08-15T18:11:13.373 回答
2

这是因为您没有初始化testStruct成员。你在这里有一个未定义的行为。它包含垃圾值。

如果您希望它始终初始化为NULL,您可以执行以下操作:

class TestClass
{
public:
    TestClass(): testStruct(NULL) {}
    TestStruct* testStruct;
};

或者使用c++11方式:

class TestClass
{
public:
    TestStruct* testStruct{NULL}; // or TestStruct* testStruct = NULL;
};

现场的所有三个例子:http: //ideone.com/ge25Zr


正如评论中所说,要使用 C++11 方式完成,您可以使用nullptr

class TestClass
{
public:
    TestStruct* testStruct = nullptr; // or TestStruct* testStruct{nullptr};
};

顺便说一句,保持成员属性私有或至少受保护是一种更好的做法。您应该创建访问器来检索它们。

于 2013-08-15T18:11:22.530 回答