あなたの宣言とそのメンバーの内訳はやや散らかっています:
を削除しますtypedef
typedef
どちらも必須ではなく、C++のクラス/構造体宣言には望ましくありません。あなたのメンバーは、pos
あなたの現在のコンパイルの失敗の核となる、書かれたままの宣言についての知識を持っていません。
これを変える:
typedef struct {....} pos;
これに:
struct pos { ... };
無関係なインラインを削除する
クラス定義自体の中でメンバー演算子を宣言および定義しています。inline
実装が現在の場所(クラス定義)に残っている限り、キーワードは必要ありません。
*this
必要に応じてへの参照を返す
これは、実装内の豊富なコピー構造に関連しており、そうする強い理由がない限り実行すべきではありません。これは、次の表現イデオロギーに関連しています。
a = b = c;
これはに割り当てc
られb
、結果の値b
はに割り当てられa
ます。これは、あなたが考えるかもしれないことに反して、次のコードと同等ではありません:
a = c;
b = c;
したがって、代入演算子は次のように実装する必要があります。
pos& operator =(const pos& a)
{
x = a.x;
y = a.y;
return *this;
}
ここでも、これは必要ありません。デフォルトのコピー代入演算子は、上記を無料で実行します(そしてコード!woot!)
注:コピー/スワップのイディオムを優先して、上記を回避する必要がある場合があり。この特定のケースでは必要ありませんが、次のようになります。
pos& operator=(pos a) // by-value param invokes class copy-ctor
{
this->swap(a);
return *this;
}
次に、スワップメソッドが実装されます。
void pos::swap(pos& obj)
{
// TODO: swap object guts with obj
}
これを行うには、クラスcopy-ctorを使用してコピーを作成してから、例外安全スワッピングを使用して交換を実行します。その結果、受信したコピーはオブジェクトの古い内臓を離れ(そして破壊し)、オブジェクトはそこの所有権を引き継ぎます。コピー/スワップのイディオムの詳細と、その中の長所と短所をここで読んでください。
必要に応じて、const参照によってオブジェクトを渡します
すべてのメンバーへのすべての入力パラメーターは、現在、呼び出し時に渡されているものすべてのコピーを作成しています。このようなコードでは些細なことかもしれませんが、より大きなオブジェクトタイプでは非常にコストがかかる可能性があります。ここに例を示します。
これを変える:
bool operator==(pos a) const{
if(a.x==x && a.y== y)return true;
else return false;
}
これに:(これも簡略化されています)
bool operator==(const pos& a) const
{
return (x == a.x && y == a.y);
}
何もコピーされないため、コードがより効率的になります。
最後に、あなたの質問に答える際に、として宣言されたメンバー関数または演算子とそうでないものの違いは何const
ですか?
メンバーは、そのconst
メンバーを呼び出すと、基になるオブジェクトが変更されないことを宣言します(可変宣言は耐えられません)。オブジェクト、または参照とポインターconst
に対して呼び出すことができるのは、メンバー関数のみです。たとえば、はローカルオブジェクトを変更しないため、として宣言する必要があります。ローカルオブジェクトを明確に変更するため、演算子はである必要はありません。const
const
operator +()
const
operator =()
const
概要
struct pos
{
int x;
int y;
// default + parameterized constructor
pos(int x=0, int y=0)
: x(x), y(y)
{
}
// assignment operator modifies object, therefore non-const
pos& operator=(const pos& a)
{
x=a.x;
y=a.y;
return *this;
}
// addop. doesn't modify object. therefore const.
pos operator+(const pos& a) const
{
return pos(a.x+x, a.y+y);
}
// equality comparison. doesn't modify object. therefore const.
bool operator==(const pos& a) const
{
return (x == a.x && y == a.y);
}
};
EDIT OPは、代入演算子チェーンがどのように機能するかを確認したいと考えていました。以下は、これがどのように行われるかを示しています。
a = b = c;
これと同等です:
b = c;
a = b;
そして、これは必ずしもこれと同じではありません:
a = c;
b = c;
サンプルコード:
#include <iostream>
#include <string>
using namespace std;
struct obj
{
std::string name;
int value;
obj(const std::string& name, int value)
: name(name), value(value)
{
}
obj& operator =(const obj& o)
{
cout << name << " = " << o.name << endl;
value = (o.value+1); // note: our value is one more than the rhs.
return *this;
}
};
int main(int argc, char *argv[])
{
obj a("a", 1), b("b", 2), c("c", 3);
a = b = c;
cout << "a.value = " << a.value << endl;
cout << "b.value = " << b.value << endl;
cout << "c.value = " << c.value << endl;
a = c;
b = c;
cout << "a.value = " << a.value << endl;
cout << "b.value = " << b.value << endl;
cout << "c.value = " << c.value << endl;
return 0;
}
出力
b = c
a = b
a.value = 5
b.value = 4
c.value = 3
a = c
b = c
a.value = 4
b.value = 4
c.value = 3