1
#include <iostream>

class Hello {
public:
    void Test() {
        std::cout << "Testing" << std::endl;
    }
};

class Hi {
public:
    Hi()
    :hello(new Hello())
    {}

    ~Hi()
    {
        delete hello;
    }

    void Testing() const {
        hello->Test();
    }

private:
    Hello  * hello;
};

int main(int argc, char ** argv) {
    Hi hi; ;
    hi.Testing();
    return 0;
}

私が知っているように、定数メンバー関数内で非定数メンバー関数を呼び出すことはできませんが、上記のコードがどのように正常にコンパイルされ、期待される結果が得られたか.

4

3 に答える 3

2

内部Hi::Testingでは、hiオブジェクトは「const」です。つまり、helloそのメソッド内でポインターを変更することはできません。(あたかもそのメソッドの期間helloとして定義されているかのようです。)Hello * const hello;

helloしかし、これはconst へのポインター (のようになります) に変換されるという意味ではありませんHello const * const hello;。が指すオブジェクトhelloは const ではないため、非 const メソッドを無制限に呼び出すことができます。

于 2012-12-28T13:52:14.313 に答える
2

問題を次の状況に減らすことができます。

Foo x;

Foo       *       p1 = &x;
Foo       * const p2 = &x;

p1->non_const_method();     // OK
p2->non_const_method();     // OK

Foo const *       q1 = &x;
Foo const * const q2 = &x;

q1->non_const_method();     // error
q2->non_const_method();     // error

Hi-object が定数であるかどうかは、この類推の最上位の 修飾子 (つまり、 または であるかどうか) にのみ影響します。ただし、最初のconst 修飾子はポインター型自体の不可欠な部分です (オブジェクトの定数の影響を受けません)。constHi::helloHello *Hello * const

于 2012-12-28T14:00:37.110 に答える
1

const オブジェクトへのポインターがある場合は、ターゲット オブジェクトで const メンバー関数を呼び出すことが制限されます。

(通常の) オブジェクトへの const ポインターは、ポインター自体を変更できないことを意味します。通常のオブジェクトへのポインターであるため、const メンバー関数だけでなく、任意のメンバー関数を使用できます。ターゲット オブジェクトにその関数の const および通常のオーバーロードがある場合、通常のオーバーロードが選択されます。

const オブジェクトのメンバーとしてポインターがある場合、最初ではなく 2 番目を取得します。

于 2012-12-28T14:07:01.803 に答える