10

それはばかげているように聞こえるかもしれません.C++prime 5th edition P258では、次のように書かれています:

既定では、this の型はクラス型の非 const バージョンへの const ポインターです。たとえば、既定では、Sales_data メンバー関数内の this の型は Sales_data *const です。

this* は const ポインターであることを理解できます。これは、初期化されたオブジェクトが指すオブジェクトは変更できないことを意味しますが、次のように述べています。

これは暗黙的ですが、通常の初期化規則に従います。つまり、(デフォルトでは) これを const オブジェクトにバインドすることはできません。

しかし、私は次のコードを書きましたが、それでも問題なくコンパイルされました:

class Test{
public:
    Test() = default;
    Test(const string &s): teststr(" ") {};
    Test(int a) : testint(a) {};
    Test(const string &s, int a): teststr(s), testint(a) {};
    string getstr() const { return teststr; };
    int getint() { return testint; };   //there is no const here
private:
    string teststr;
    int testint = 0;
};

int main(){
    Test a("abc",2);

    cout << a.getint() << " ";
    cout << a.getstr() << endl;
    cout << endl;

    return 0;
}

私の質問は次のとおりです。「const」があるかどうかに関係なく、コンパイラがそれを正常にコンパイルできる場合、なぜそれが重要なのですか? そして、本は次のように述べています。

結局のところ、isbn の本体は this が指すオブジェクトを変更しないので、これが const へのポインターであれば、関数はより柔軟になります。

柔軟性とは何ですか?いくつかの例を見せていただけますか?

4

5 に答える 5

13

初心者のthis場合、定数ポインターとして示されることがよくあります。

ただし、this実際にはポインター型の prvalue (純粋な右辺値) です。の「const-ness」を意味する基本型の prvalues には何も代入できませんthis

の正確なタイプはthis、メソッドの cv 修飾に依存します。経験則では、cv-qualification は通常のポインター型の先頭に追加するだけです。つまり、メソッドClassがマークされているconst場合、型はconst Class*です。

「const」があるかどうかに関係なく、コンパイラがそれを正常にコンパイルできる場合、なぜそれが重要なのですか?

thisの指す先の型がである場合 (およびその場合にのみ) const、クラスのメンバーを変更することはできません。

Class const* ptr; // ptr->data is also const, not modifiable through this pointer

Class* ptr; // ptr->data isn't const - can be modified.

メソッドの-qualifier を使用すると、オブジェクトのメソッドと非オブジェクトconstのメソッドを区別できます。これはしばしば必要になります。constconst

于 2014-12-22T16:23:11.580 に答える
5

「これについては*がconstポインターであることを理解できます。これは、初期化されたオブジェクトが指すオブジェクトを変更できないことを意味します。しかし、次のように言います:」

いいえ、あなたはこれを間違えました。constポインターthisであることは、ポインターの値自体を次のように変更できないことを意味します。

 class MyClass {
      void foo() {
          MyClass a;
          this = &a; // <<< Compiler error
      }
 }

の型はthis実際には次のように表示されます

 MyClass * const this;

およびconstインスタンスまたは参照用

 MyClass const * const this;

とは異なりますのでご注意ください。

 const MyClass* some_const_instance_pointer;
于 2014-12-22T16:22:59.703 に答える
5

const「柔軟性」とは、定数であるかどうかにかかわらず、任意のオブジェクトで関数を呼び出すことができることです。オブジェクト (または への参照/ポインター) で非const関数を呼び出すことはできません。constconst

したがって、次の場合は失敗します。

const Test c;
cout << a.getint() << " ";   // ERROR: non-const function
cout << a.getstr() << endl;  // OK: const function

この柔軟性に加えて、メンバー関数を宣言することconstは、想定されていない関数内のオブジェクトを誤って変更することを防ぐため、良い考えです。

于 2014-12-22T16:23:06.800 に答える
4

二問二答。

ポインターを再割り当てすることはthisできません。constそれがこの場合の意味です。指し示すオブジェクトの内容は変更できますが、this指しているオブジェクトを変更することはできません。

メソッドを作成することのさらなる柔軟性は、非 const オブジェクトのconst両方で使用できることです。const非 const メソッドはconstオブジェクトで使用できません。

例:

class A {
    int a;
    public:
    int method() const {
        return a;
    }
};

void f() {
    A a;
    const A ca;

    a.method();
    ca.method();
}
于 2014-12-22T16:23:41.083 に答える