0

メンバー関数にアクセスするために、初期化されていないポインター オブジェクトを使用しています。それは機能し、私はそれがどのように機能するかを知っています。しかし、そのクラスを B で派生させ、そのメンバー関数にアクセスしようとすると、セグメンテーション違反が発生します。2つの異なる動作を示す理由を誰かが説明できますか?

以下はプログラムです: 29 行目にコメントを付けると動作しますが、それがないと失敗します。

#include <iostream>

using namespace std;

class A
{
    int no;
public:
void printml(int i)
    {
        no = i;
        cout << "in base: value"<<no;

    }
 };
class B:public A
    {
        public:
        void printdl()
        {
            cout << "in derived" ;
        }
    };

int main()
{
    A *ptr;
    B *ptr1;
    ptr->printml(1);
    ptr1->printml(1);
    return 0;
}
4

3 に答える 3

4

初期化されていないポインタの間接参照は、未定義の動作です。なぜクラッシュしてはいけないと思いますか?

于 2012-07-17T05:18:57.357 に答える
0

->初期化されていないポインタまたはヌル ポインタに対して逆参照演算子 ( ) を初めて使用したときに、コードでセグメンテーション違反が発生する可能性が高くなります。これは未定義の動作です。つまり、それがうまくいったとしても、エラーを探しているコンパイラによって誤解されたため、それは単なる運、または運が悪かったということです。

次のようなポインターを使用します。

A *ptr = new A();
ptr->printml(1);
于 2012-07-17T05:25:56.050 に答える
0

関数を呼び出すと、次のことが起こります。1) コンパイラはオブジェクトの型 (コンテンツではない) をチェックし、その型のメンバー関数を呼び出します。2) このポインター (オブジェクト自体を指すポインター) を最初のパラメーターとしてメンバー関数に渡します。3) このポインターを暗黙的に使用してメンバー変数を呼び出します。

上記の点を考慮すると、メンバー関数内でメンバー変数を使用していない場合、このポインターは使用されないため、クラッシュせず、メンバー変数を使用するとクラッシュします。

それでもこれは未定義の動作と見なされ、初期化せずにポインター オブジェクトを使用してはなりません。

于 2012-07-17T07:15:57.997 に答える