字符串和函数对象
String and function object
我遇到了这个问题,但我不确定该怎么做...
class Goo
{
char _ch;
string _str;
public:
function<void(void)> dobedo;
// Constructor 1
Goo(string s) : _str(s)
{
cout << "Constructed: [" << &_str << "]: " << _str << endl;
dobedo = [&]()
{
cout << "Dobedo: [" << &_str << "]: "<< _str << endl;
};
}
// Constructor 2
Goo(char ch) : _ch(ch)
{
dobedo = [&]() {
cout << "Dobedo: " << _ch << endl;
};
}
void show() { cout << "Show: [" << &_str << "]: " << _str << endl; }
};
int main()
{
string myStr1("ABCD");
string myStr2("EFGH");
vector<Goo> goos;
goos.push_back(Goo(myStr1));
goos.push_back(Goo(myStr2));
goos[0].dobedo();
goos[1].dobedo();
goos[0].show();
goos[1].show();
return 0;
}
由于某种原因,函数对象无法打印_str,尽管能够找到内存地址:
Constructed: [00EFF80C]: ABCD
Constructed: [00EFF7B0]: EFGH
Dobedo: [00EFF80C]:
Dobedo: [00EFF7B0]:
Show: [032F2924]: ABCD
Show: [032F296C]: EFGH
不过,我对字符变量没有任何问题。
int main()
{
vector<Goo> goos;
goos.push_back(Goo('#'));
goos.push_back(Goo('%'));
goos[0].dobedo();
goos[1].dobedo();
return 0;
}
输出给出:
Dobedo: #
Dobedo: %
有什么想法吗?
在未定义复制构造函数的情况下,代码中存在未定义的行为。默认复制构造函数按值复制所有成员。因此,您的lambda对象被复制,并且它包含对已销毁对象的引用 - _str
(当在调用方法时必须重新分配向量时push_back
(。
为类定义复制构造函数和移动构造函数Goo
:
Goo(const Goo& g)
{
_str = g._str;
dobedo = [&]()
{
cout << "Dobedo: [" << &_str << "]: "<< _str << endl;
};
}
Goo(Goo&& g)
{
_str = move(g._str);
dobedo = [&]()
{
cout << "Dobedo: [" << &_str << "]: "<< _str << endl;
};
}
您的输出清楚地表明构造函数中 _str
的地址与 show
中的地址不同。这意味着您的对象已被复制/移动。它可能在被推送到向量时发生。顺便说一句,当您将其他元素推送/弹出向量时,它也可能发生,因为向量不能保证元素保持在同一内存地址。
创建dobedo
函子时,所有捕获的字段都将复制到其中。在第一种情况下,当对象被复制/移动时,_str
的地址变得无效(没有人在移动/复制时更新它!有时我们可能会在该地址找到类似空字符串的东西(尽管现在访问它是内存违规(。在第二种情况下,字符被捕获并存储 - 并且在任何对象位置更改时它肯定保持有效。
相关文章:
- 如何创建对象函数指针C++映射?
- 为什么我可以改变常量对象中的成员变量,这是返回常量对象函数的结果?
- 如何将对象函数的实例传递给另一个函数
- 调用模板函数的问题"No matching function for call"参数:迭代器、对象函数
- makefile对我的名称空间对象/函数/构造函数的不确定引用
- 将对象函数转换为函数指针
- 非对象函数/类函数C++
- 线程对象函数 C++
- C 将成员对象函数分配给类成员功能
- 使用基本指针调用派生对象函数
- 可以(通过编译器)使用多少个线程来初始化全局对象(函数main之前)
- C++类对象函数
- 对对象::函数的未定义引用
- 无法弄清楚将多个对象函数作为单独的线程调用的语法
- 在提升作用域出口中调用对象函数
- 使用基指针来使用派生对象函数
- 在for_each lambda 中调用对象函数
- C++:: 模板函数 - 从对象函数获取对象的地址
- Qt5 未解析的外部静态元对象函数
- 通过变量使用对象和对象函数