3

私は C++ を学んでおり、現在クラスで練習しています。プレイヤーの名前とスコアを格納し、データを操作して表示する関数を定義するクラスを作成しました。

私が作成した関数の 1 つは、2 人のプレーヤーのスコアを比較し、スコアが高いプレーヤーへのポインターを返すことです。これは機能です:

Player * Player::highestScore(Player  p2)const
{
    if(p2.pScore>pScore)
    {
        return &p2;
    }
    else
    {
        return this;
    }
}

メインから、次のプレーヤーを作成します。

Player p1("James Gosling",11);
Player *p4 = new Player("Bjarne Stroustrup",5);

私は、highestScore 関数を呼び出します。

Player *highestScore = p1.highestScore(*p4);

ただし、関数自体を読んで気づいたかもしれませんが、メソッドを呼び出したオブジェクトへのポインターを返すと (スコアが高い場合)、次のようなエラーが表示されます。

return value type does not match the function type

次のように、関数の戻り値の型を a として宣言すると、この問題は解消されるconstようです。

const Player * Player::highestScore(Player  p2)const

私を混乱させている部分は、関数を呼び出したオブジェクトへのポインターであるを返すことを許可しないreturn &p2のはなぜですか? また、関数の戻り値の型を const として宣言しても、パラメーターに渡された引数が const の Player オブジェクトではない場合でも、それを行うことができますか?constthisconstreturn &p2

質問が奇妙に思えたり、私がやろうとしていることが非常に悪いプログラミングである場合は申し訳ありませんが、それはそれを行うことによって学習することを目的としています.

4

3 に答える 3

7

私を混乱させている部分は、const ではない &p2 を返すことを許可し、const ではない関数を呼び出したオブジェクトへのポインターである this を返すことを許可しない理由です。 ?

this すべてのデータ メンバーと同様に、メンバー関数内のisconst (または、より正確には、 is a pointer-to- const) :const

#include <iostream>
#include <type_traits>

struct A
{
    void foo()
    {
        std::cout << std::is_same<decltype(this), const A*>::value << '\n';
    }

    void bar() const
    {
        std::cout << std::is_same<decltype(this), const A*>::value << '\n';
    }
};

int main()
{
    A a;
    a.foo();
    a.bar();
}

出力:

0
1

また、関数の戻り値の型を const として宣言した場合でも、パラメーターに渡された引数が const の Player オブジェクトでなくても、&p2 を返すことができますか?

何を試したかはわかりませんが、おそらく でしたPlayer* const。これはPlayer const*(またはconst Player*) とは異なります。constネスを&r2うまく追加できます。constネスを奪うことは別の話です。

于 2013-02-06T16:06:59.587 に答える
3

「const」関数がある場合、「この呼び出しでオブジェクトインスタンスを変更しない」ことをほぼ約束します。コンパイラはそのタイプの関数を作成します(ここで、Tはクラスのタイプです。たとえばthis)。const T* thisPlayer

const明らかに、非ポインタと同じようなものへのポインタを返すことはconstルール違反です-あるコードがオブジェクトへの非constポインタを持っていると、コードはオブジェクトを変更する可能性があります...これは「この関数は変更されません」。

constしたがって、関数からの戻り型に追加することが、ここでの正しい解決策です。

また、入力としてasを受け取るようにコードを変更することもできconst *Player p2ます。現在のコードは、ローカル変数へのポインターを返します[これは引数ですが、同じ原則です。関数呼び出しが戻ってきた]。

編集:属性を持つ関数で実際に何かのコピー(たとえば、整数、文字列、またはたとえばnewで割り当てられた新しい構造)を返す場合を除いてconst、戻り型は。である必要がありますconst

于 2013-02-06T16:12:51.823 に答える
3

const メソッドと非 const メソッドの違いは、最初はthisconst のポインターであり、後者はそうではないことです。そのため、const 関数から非 const ポインターを返してこれを返そうとすると、const がthisあり、const-ness を自動的に削除できないため、コンパイラは文句を言います。

&p2は単に引数へのポインタであるため、const ではありません。これはローカル変数へのポインターであり、それを返すこと&p2は決して安全ではありませんが、覚えておいてください。

于 2013-02-06T16:07:30.770 に答える