2012-02-04 7 views
3

リファレンスを含むオブジェクトをベクターに入れたいのですが...参照メンバ変数を持つクラスのoperator =()を実装するには?

ベクターにプッシュしたいオブジェクトのメンバ参照の代わりにスマートポインタを使用する必要がありますか?これは私がやりたいことだった:

#include <string> 
#include <vector> 
using namespace std; 

class MyClass { 
    public: 
    MyClass(const string& str_ref); //constructor 
     MyClass(const MyClass& mc);  //copy constructor 
    private: 
     string& my_str; 
}; 

MyClass::MyClass(const string& str_ref) : 
    my_str(str_ref) 
{} 

MyClass::MyClass(const MyClass& mc) : 
    my_str(mc.my_str) 
{} 


int main() { 

    //create obj and pass in reference 
    string s = "hello"; 
    MyClass my_cls(s); 

    //put into vector 
    vector<MyClass> vec; 
    vec.push_back(my_cls); 

    return 0; 
} 

//Throws Error 
//ref.cpp:6:7: error: non-static reference member ‘std::string& MyClass::my_str’, can’t use default assignment operator 

それは私が自分自身の演算子=を(実装する必要があると言うが)デフォルトは1を生成して、有効ではありませんもちろん、そうするための法的な方法はありません。 ..

#include <string> 
#include <vector> 
using namespace std; 

class MyClass { 
    public: 
    MyClass(const string& str_ref); //constructor 
     MyClass(const MyClass& mc);  //copy constructor 

     MyClass operator=(const MyClass& mc);  //operator = 

    private: 
     string& my_str; 
}; 

MyClass::MyClass(const string& str_ref) : 
    my_str(str_ref) 
{} 

MyClass::MyClass(const MyClass& mc) : 
    my_str(mc.my_str) 
{} 

//not a constructor. should not construct new object 
//and return that? 
MyClass MyClass::operator=(const MyClass& mc) { 
    if (this != &mc) {     //test for self-assignment. 
    my_str(mc.my_str);   //can't reseat refs. this shouldn't work. 
    } 

    return *this; 
} 

int main() { 

    //create obj and pass in reference 
    string s = "hello"; 
    MyClass my_cls(s); 

    //put into vector 
    vector<MyClass> vec; 
    vec.push_back(my_cls); 

    return 0; 
} 

//THROWS: 
//ref2.cpp: In constructor ‘MyClass::MyClass(const string&)’: 
//ref2.cpp:18:19: error: invalid initialization of reference of type ‘std::string& {aka //std::basic_string<char>&}’ from expression of type ‘const string {aka const //std::basic_string<char>}’ 
//ref2.cpp: In member function ‘MyClass MyClass::operator=(const MyClass&)’: 
//ref2.cpp:29:18: error: no match for call to ‘(std::string {aka std::basic_string<char>}) //(std::string&)’ 

ここで、スマートポインタを参照以外のものにする必要がありますか?

編集:これは簡単です。文字列&は渡されるオブジェクトではありませんが、それはベクトルオブジェクトを含むより複雑なオブジェクトです。

+1

プレーンストリングの代わりに&を使用する特別な理由はありますか? –

+0

[静的でないconstメンバー、デフォルトの代入演算子は使用できません]の重複が可能です(http://stackoverflow.com/questions/634662/non-static-const-member-cant-use-default-assignment-operator) – Joe

答えて

6

参照番号の代わりに生ポインタを保存することができます。生ポインタは再配置することができるので、C++で再コンパイル可能な参照をエミュレートする良い方法です。

class MyClass 
{ 
public: 
    MyClass(const string& str_ref); 
    MyClass(const MyClass& mc); 
    // by the way, operator= should return a reference 
    MyClass& operator=(const MyClass& mc); 
private: 
    string* my_str; 
}; 

この方法で、operator=は、実装するための楽勝になります。

+0

私はあなたが言っていることを理解していますが、私は参照を「嫌いです」。ここでは、私は何かを 'new'または' delete'する必要はありませんが、誰かが誤って私が削除することを忘れてしまったと仮定して、プロジェクトに壊れたコードを追加するかもしれません。しかし、私はスマートなポインタを使うべきであるという指示として、私はあなたの回答を喜んで受け入れていると思います。 – Philluminati

+0

これでスタックに宣言された何かを暗黙的に '削除 'しようとするので、スマートなポインタを使うことはできません。 – Philluminati

+1

@Philluminatiあなたのコードを他の人が邪魔するのを防ぐために、あなたは何を防げているのでしょうか?それはあなたのソリューションが唯一有効なものであることを意味しますか? –

5

std::reference_wrapper<T>はどうですか?今ではスマートポインタを許可するようにコードをリファクタリングする必要はありませんが、後で誰かが来て、deleteと思われる内部ポインタも使用していません。

class MyClass 
{ 
    public: 
     MyClass(string &str_ref) 
     : my_str(std::ref(str_ref)) 
     { 
     } 

    private: 
     std::reference_wrapper<std::string> my_str; 
}; 
+0

私はこの答えが本当に好きです。私は 'std :: reference_wrapper'について聞いたことがありませんでした。ありがとうございました。 – Philluminati

+0

あなたは受け入れられた答えをいつでも変更できます。 :D – moswald

+0

すぐに私はそれが働くようになる... ;-) – Philluminati

0

あなたはまだあなたがstd::reference_wrapperのそれ以外の優れた提案を使用することはできませんあなたのメンバー(すなわちstd::string& operator=(std::string const&))の代入演算子を使用することができるようにしたい場合。しかし、コピーコンストラクタを使用してオブジェクトを最初から再構築することができます。したがって、メンバーは実際には未加工の参照である可能性があります。

MyClass& MyClass::operator=(MyClass const& from) { 
    this->~MyClass(); 
    new(this) MyClass(from); 
    return *this; 
} 
関連する問題