用reference_wrapper本地初始化向量
Initializing vector with reference_wrapper's locally
我想从标准容器使用许多与继承相关的类型(std::reference_wrapper
是此类容器AFAIU的正确值类型(。但是,我不明白,当插入到映射中的引用的值不是全局变量时,如何初始化这样的容器。例如:
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
struct I
{
virtual void print() = 0;
};
struct S1: public I
{
void print() override
{
cout << "S1 " << i << endl;
}
int i{};
};
struct S2: public I
{
void print() override
{
cout << "S2 " << f << endl;
}
float f{};
};
std::vector<reference_wrapper<I>> v;
void init()
{
S1 x{};
S2 y{};
v.emplace_back(x);
v.emplace_back(y);
}
int main()
{
init();
v[1].get().print();
return 0;
}
这样可以编译,但是我在运行时遇到一些内存损坏。初始化std::reference_wrapper
s 容器的正确方法是什么?
不能引用函数本地对象。 一旦函数退出,这些本地对象就会被销毁,你在向量中留下悬而未决的引用。 要解决此问题,您可以做的是切换到使用std::unique_ptr<I>
和std::make_unique
动态分配要存储在矢量中的对象。std::unique_ptr
将管理内存,一旦向量被销毁,它将破坏向量中的std::unique_ptr
,它们将依次删除为保存对象而获取的内存。 那会给你
#include <iostream>
#include <vector>
#include <functional>
#include <memory>
using namespace std;
struct I
{
virtual void print() = 0;
};
struct S1: public I
{
void print() override
{
cout << "S1 " << i << endl;
}
int i{};
};
struct S2: public I
{
void print() override
{
cout << "S2 " << f << endl;
}
float f{};
};
std::vector<unique_ptr<I>> v;
void init()
{
v.emplace_back(std::make_unique<S1>()); // creates a defaulted S1 in the unique_ptr
v.emplace_back(std::make_unique<S2>()); // creates a defaulted S2 in the unique_ptr
}
int main()
{
init();
v[1]->print(); // or (*v[1]).print()
return 0;
}
您面临的问题是您的对象S1 x
和S2 y
在init
函数结束时被销毁。所以,在init()
末尾,你的向量v
包含对任何内容的引用。因此,当尝试调用print()
时,您会得到一个segmentation fault
。
以类似的方式,考虑以下代码:
int& get_i()
{
int i = 1;
return i;
}
int main()
{
std::cout << get_i() << std::endl; // segmentation fault
return 0;
}
这也会产生一个segmentation fault
,因为get_i()
返回对局部变量的引用(如果get_i()
,则在最后销毁(。
您可以改用用户std::unique_ptr
,如其中一条评论中所述。
相关文章:
- 如何使用C++初始化向量;脚本化值不是数组、指针或矢量错误
- 在C++中初始化向量映射的最有效方法
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- 用向量的向量元素初始化向量的空向量
- 初始化向量数组,其中每个向量的大小为 0
- 如何初始化向量<unordered_map<*,*>>
- 如何在元组初始化向量中删除样板?
- C++ 通过函数声明后初始化向量
- 特征::向量;在函数中使用 Eigen::Matrix3f 的值初始化向量,大于 4 个条目
- 使用所述填充构造函数初始化向量中的向量
- 制作可用于初始化向量的迭代器
- 如何使用sregex_token_iterator对象初始化向量
- 用空向量 c++ 的 M 元素初始化向量
- 用reference_wrapper本地初始化向量
- 将向量元素与字符串元素进行比较,而不初始化向量
- 使用 reference_wrappers 初始化向量
- 从不同类型的容器的迭代器初始化向量
- 在具有容量/调整大小的类中初始化向量
- 在头文件中声明和初始化向量
- 错误:调用'begin(long double [nPoints])'没有匹配函数;使用硬编码的 int 与整数变量初始化向量