代入演算子 ( =
) は常に右辺値を左辺値にコピーする必要がありますか?それとも操作対象のオペランドの型に完全に依存していますか? ばかげて申し訳ありませんが、私が何を読んでも、右側の値を左側にコピーするだけであると書かれています。私は自分の事実を正しく理解したい。
C++ での例を教えてください。
代入演算子 ( =
) は常に右辺値を左辺値にコピーする必要がありますか?それとも操作対象のオペランドの型に完全に依存していますか? ばかげて申し訳ありませんが、私が何を読んでも、右側の値を左側にコピーするだけであると書かれています。私は自分の事実を正しく理解したい。
C++ での例を教えてください。
代入演算子とクラスの構成を実装する方法に完全に依存しています... C ++では、PODクラスまたは構造体のデフォルトのコンパイラ作成代入演算子メソッドは、RHSのビットごとのコピーを単純に行いますオブジェクトを LHS オブジェクトに変換しますが、ユーザー定義の代入演算子を使用すると、必要なことを何でも実行できます。これは常に LHS オブジェクトに属しますが、コピーを行う必要はなく、必要に応じてさまざまな副作用が発生する可能性があります。
代入演算子は好きなようにオーバーロードできますが、C++ での通常の実装は次のようになります。
class MyObject
{
public:
MyObject& operator=(const MyObject& rhs)
{
if (this != &rhs)
x = rhs.x;
return *this;
}
private:
int x;
};
これを行う理由は、カスタム オブジェクトの簡単な割り当てを可能にするためです。ユーザー定義のクラスと構造体は複雑になる可能性があるため、ポインター メンバーのディープ コピーなどを行うためにカスタム代入演算子を提供する必要がある場合があります。
MyObject a;
MyObject b;
b = a; // calls assignment operator b.operator=(a);
C では演算子をオーバーロードできないことに注意してください。Java ではおそらく別の方法で行われます。
編集:
Griwes が指摘したように、他に知っておくべきことは、ユーザー定義オブジェクトを指定しないと、コンパイラが暗黙的な代入演算子を生成するということです。コンパイラによって生成されるデフォルトの動作を回避するために、単に定義または宣言したい場合があります。
=
たとえば、以前のユースケースを次のように変更した場合、実際にコピーコンストラクターを呼び出すトークンの使用法もいくつかあります。
MyObject a;
MyObject b = a; // this calls the copy constructor (also implicitly defined if not provided)
割り当てのように見えるかもしれませんが、上記の場合、カスタム提供のオペレーターは呼び出されません。代入演算子を定義する場合と定義しない場合の背後にあるその他の理由については、ウィキペディアの 3 の規則を参照してください。
代入演算子 (=) は常に右辺値を左辺値にコピーする必要がありますか?
いいえ。ユーザー定義型の場合、そのようなことはありません。むしろ、適切なoperator=
関数を呼び出します。次のクラスを検討してください。
#include <iostream>
struct Half {
int i;
void operator=(int j) { i = j/2; }
};
struct Double {
int i;
void operator=(int j) { i = j*2; }
};
int main () {
Half h;
h = 3;
Double d;
d = 3;
std::cout << h.i << " " << d.i << "\n";
// Result is "1 6"
}
ご覧のとおり、代入演算子は、適切と思われるアクションを自由に実行できます。この場合、単なる「コピー」ではないことは明らかです。
異なる言語は異なる概念を使用します
Java と C++ と C+ はい、別の関数によってオーバーロードされない限り、これは代入です
T-SQL = テストと代入になる
コピーという用語は一般的すぎます。
C では、ポインターに割り当てると、実際の値はコピーされませんが、右側のオペランドが格納されているメモリ アドレスが保存されます。
int *ptr = (int *)malloc(sizeof(int *));
*ptr = 1; // points at whatever address 1 has
ptr = 1; // points at address 1, containing ????