如何为具有引用成员变量的类实现operator =()?

Phi*_*ati 3 c++ oop operator-overloading unassigned-variable

我想要一个包含引用的对象,并将该对象放入向量中...

我必须在我想要推送到矢量的任何对象中使用智能指针而不是成员引用吗?这就是我想要做的:

#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
Run Code Online (Sandbox Code Playgroud)

但是它说我需要实现我自己的operator =(),因为默认生成的一个是无效的,但当然,没有合法的方法可以这样做......

#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&)’
Run Code Online (Sandbox Code Playgroud)

所以我被迫在这里使用智能指针或其他任何参考?

编辑:这是一个简化.String&不是传递的对象,它是一个包含矢量对象的更复杂的对象.

小智 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;
};
Run Code Online (Sandbox Code Playgroud)

这样,operator=将是一个很好的实施.

  • @Philluminati:在使用智能指针的代码库中,查看原始指针并不意味着"omg他可能忘记删除它",这意味着这是一个临时的非拥有指针.当然你可以制作一个"智能"指针来明确缺乏所有权,怎么样`template <typename T> struct non_owning_ptr {typedef T*type; 然后使用`non_owning_ptr <const string> :: type my_str`. (2认同)
  • @Kerrek:但代码应尽可能自我记录.这可能是反对"原始"指针语法的最佳参数. (2认同)

mos*_*ald 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;
};
Run Code Online (Sandbox Code Playgroud)