3

タイトルは基本的にはすべてです。私は主に他のAPIの他の関数のパラメータを初期化できるオブジェクト(たとえば、カスタム文字列オブジェクト)を作成できるように、これを行う必要があります。ここで動作するようにカスタム整数クラスを取得しようとしている私の例を示します。 C++データ型を初期化できるクラスを作成するにはどうすればよいですか?

#include <iostream> 
using namespace std; 

class test 
{ 
public: 
    int member; 
    test(int i) : member(i) {} 

    friend int &operator=(int &i, test t); 
}; 

int &operator=(int &i, test t) 
{ 
    return (i = t.member); 
} 

int main() 
{ 
    int i; 
    test t = 90; 

    cout << (i = t); 
    return 0; 
} 

は、残念ながら私は、オペレータが=メンバ関数にする必要があるというエラーを受け取ります。私は代入演算子の静的メンバー以外のオーバーロードが実装されないようにするC++標準の目標を理解していますが、これを行う他の方法はありますか?助けを借りてありがとうございます/提案!何をしようとする

答えて

3

は、あなたが(整数のみのメンバーを含む)の書き込みしようとしているクラスのために

operator int() 
{ 
    return this->member; 
} 

変換演算子を必要とする、あなたはオーバーロードする必要はありませ=オペレータ。

=演算子は、すべてのクラスに対してデフォルトでコンパイラによって生成されるメンバー関数の1つです。注意点は、クラスメンバの単純なビットコピー(浅いコピー)です。なぜなら、整数だけで十分であるからです。

ポインタをシャープにコピーすると、メンバポインタを含むすべてのオブジェクトが同じ動的メモリ位置を指しているため、ポインタをメンバ関数として動的に割り当てた場合は、=演算子をオーバーロードする必要があります&オブジェクトの1つが寿命を終えると、他のオブジェクトにはぶら下がりポインタが残されます。
@Tonyは、コメントを適切に指摘しています。浅いコピーはです。通常はですが、は必ずしもではありません。シナリオについての彼のコメントを見てください。

代入演算子をオーバーロードしたい場合は、Copy and Swap Idiomを正しい方法でチェックしてください。

Rule of Threeもチェックしてください。

+1

「[演算子=]オペランドのビットコピー(シャローコピー)することにより、単純なビットない」...オペランドが...おそらく、メンバ変数を使用するには、奇妙な用語のですか?そして、それを持つメンバのコピーコンストラクタを呼び出します。ビットごとのシャローコピー(例えば、 'std :: string')を行わないかもしれません。危険なポインタの浅いコピー:通常はそうですが、必ずしもそうではありません。(通常は 'const')静的参照データへのポインタを安全にコピーすることができます。 –

+1

@トニー:ありがとう!私はそのビットをオペランドについてメンバーに変更しました。それはそれほど冗長ではなかった。私は、ダイナミックメモリ割り当てを持つメンバポインタの最も普通の場合を言及していました。これは、オーバーロードされたものに対するデフォルトの割り当てが初心者を最も傷つけるためです。あなたのコメントは、回答を読む人に例外を解読するのに役立つはずですので、ありがとう:) –

+1

はい - 私はあなたの考えに従うことができます、ちょうど心配 "初心者"は "任意のポインタ=あなた自身の演算子が必要="ガイドラインはルール。しかし、それは良い指針であり、あなたが言うように、初心者を助ける。ダイナミックメモリは100%相関していませんが、別の危険の兆候です。 pointed-toオブジェクトは、 'main()'で呼び出されたファクトリメソッドによって返され、アプリケーション終了直前にのみ削除され、それを指すオブジェクトの存続期間がその中に含まれます)。乾杯。 –

5

これは代入演算子ではなく、オーバーロードされた型キャストで行われます。これはあなたの主な機能を期待通りにするでしょう:

#include <iostream> 
using namespace std; 

class test 
{ 
public: 
    int member; 
    test(int i) : member(i) {} 
    operator int() const {return member;} 
}; 

int main() 
{ 
    int i; 
    test t = 90; 

    cout << (i = t); 
    return 0; 
} 
+2

+1 '演算子int()'は 'const'でなければなりません。' '明示的なら' 'test(int)'はより安全です( '' test t = 90'')。 –

+0

@トニー:ヒントのおかげで。 – manol

+0

これはうまくいくようです!ありがとうございました! – AutoBotAM

1

代入演算子はフレンド関数にすることはできません。代入演算子は、非静的メンバー関数としてのみ宣言できます。これは、最初のオペランドとしてL値を受け取るようにするためです。 []、()、 - >演算子についても同様です。あなたの場合、intは組み込み型なので、メンバー関数は使用できません。演算子int()を実装して、ユーザー定義型をintにキャストすることができます。

+0

'int'で非静的メンバー関数を定義することはできません。 – unkulunkulu

+0

@unkulunkulu、yup、intは組み込み型なので、回答が更新されました。 –

3

これを試してみてください:

class test 
{ 
public: 
    int member; 
    test(int i) : member(i) {} 

    operator int() {return this->member;} 
}; 

int main(void) 
{ 
    int i; 
    test t = 90; 

    cout << (i = t); 
    return 0; 
} 
関連する問題