我希望有一个包含引用的对象,并将该对象放入向量...
我必须在任何想要推送到矢量的对象中使用智能指针而不是成员引用吗?这就是我想要做的事情:
#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
然而它说我需要实现我自己的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&)’
所以我被迫在这里使用智能指针或除了参考之外的任何东西吗?
编辑:这是一种简化。字符串和放大器;不是传递的对象,它是一个包含矢量对象的更复杂的对象。
答案 0 :(得分: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=
将很难实现。
答案 1 :(得分: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;
};
答案 2 :(得分:0)
如果您希望仍然能够使用会员的作业运算符(即std::string& operator=(std::string const&)
),则无法使用std::reference_wrapper
的其他优秀建议。但是您可以使用复制构造函数从头开始重建对象,这样您的成员实际上可能是原始引用:
MyClass& MyClass::operator=(MyClass const& from) {
this->~MyClass();
new(this) MyClass(from);
return *this;
}