web-dev-qa-db-ja.com

メンバー変数をC ++のデフォルト引数として使用するにはどうすればよいですか?

メンバー関数の1つの引数をオプションにしたい。引数が指定されていない場合は、メンバー変数を使用します。

ただし、コンパイルしようとすると、「エラー:非静的データメンバーの無効な使用 'Object :: initPos' "と表示されます。

問題を切り分けるために、私はint型をデフォルトにしてみましたが、うまくコンパイルされました。私のコードの何が問題で、どのようにしてメンバー関数をデフォルト値として使用できるのでしょうか。

ご協力ありがとうございました!

Object.h

class Object
{
    public:
       ...
       void MoveTo(double speed, Point position);

    protected:
       Point initPos; 
       Point currPos;

};

Object.c

void Object::MoveTo(double speed, Point position = initPos)
{
    currPos = postion;
}

Point.h

class Point
{
    ...

    private:
       double x;
       double y;
       double z; 
};
33
tuzzer

メンバー関数のデフォルトの引数式は、クラスまたはグローバルスコープにあるものにのみ依存できます。デフォルトの引数は、メソッドの宣言(つまり、ヘッダーファイル)でも指定する必要があります。

これを回避するには、MoveToメソッドの2つのオーバーロードが必要です。 1つの引数を取るものと2つの引数を取るもの。 1つの引数を取るメソッドは、他のメソッドを呼び出し、デフォルトと見なす値を渡します。

_void Object::MoveTo(double speed)
{
    MoveTo(speed, initPos);
}

void Object::MoveTo(double speed, Point position)
{
    // Everything is done here.
}
_

MoveTo(double)を呼び出してMoveTo(double, Point)を呼び出すと、MoveToの実装を1回だけ記述できるため、 [〜#〜]を尊重することに注意してください。ドライ[〜#〜] 原則。

41
Emile Cormier

デフォルト値はプロトタイプの一部ではありません。つまり、デフォルト値は関数自体ではなく、呼び出し元によって解決されます。したがって、最初に、それらは発信者に表示される必要があります。次に、保護されたクラスのメンバーにアクセスできません。 (デフォルトでパブリックメンバーを使用することもできないと確信していますが、チェックするのが面倒です。)

この問題を解決するには、他の回答で提案されているように、チェーンされたオーバーロードを使用します。

12

あなたはそのようにあなたの関数メンバーをオーバーロードすることができます:

void Object::MoveTo(double speed, Point position) {
   ....
}

void Object::MoveTo(double speed) {
   Point position = this->initPos;

   MoveTo(speed, position);
}
1
damson