I want to have an object that contains a reference, and put that object into a vector...
Must I use smart pointers instead of a member references in any object I want to push into a vector? This was what I wanted to do:
#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
However it says I need to implement my own operator=() as the default generated one isn't valid but of course, there is no legal way to do so...
#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&)’
So am I forced to use a smart pointer here or anything other than a reference?
EDIT: This is a simplification. String& is not the object being passed, it's a more complex object itself containing a vector object.
You can store a raw pointer instead of a reference here. Raw pointers can be reseated, and so they're a good way to emulate reseatable references in 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;
};
This way, operator=
will be a cinch to implement.