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

答え

私にとっては、両方の質問に「それはNULLではありません」と表示され、NULLとして取得される場合があります

上記のシナリオが発生する理由は、C++ が変数に自動的に何も割り当てないためです。したがって、未知の値が含まれています。

そのため、不明な値は NULL になる場合もありますが、そうでない場合もあります

この理論をテストする最善の方法は、Visual C++ と g++、およびその他の C++ コンパイラで試してみることです。

null または null 以外を取得するもう 1 つの理由は、さまざまな方法でアプリケーションをコンパイルすると、コンパイラがさまざまな実行可能ファイルを出力するため、1 つの未定義変数シナリオでコンパイラが実行可能ファイルを出力し、実行時に未定義変数が NULL を指す可能性があることです。または NOT NULL

GNU C++ コンパイラと Microsoft コマンド ライン コンパイラを使用したテスト

警告 このコードを使用しないでください IT'S BAD (これは、2 つのコンパイラでの未定義変数シナリオのテストです)

コード (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

testStructNULL になることもあれば、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;
};

ライブの 3 つの例すべて: http://ideone.com/ge25Zr


コメントで述べられているように、C++ 11 の方法で完了するには、次を使用できますnullptr

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

ところで、メンバー属性を非公開にするか、少なくとも保護することをお勧めします。それらを取得するには、アクセサーを作成する必要があります。

于 2013-08-15T18:11:22.530 に答える