插入向量时的 C++ 临时对象
c++'s temporary objects when inserted to a vector
我正试图让这段代码正常工作,但对象不断被破坏。。。我发现这与对象被复制到向量有关,但找不到任何方法来阻止它…
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Obje
{
private:
static int instances;
int id;
public:
static int getInstances();
void getId();
virtual void myClass();
Obje(int auxId);
~Obje();
};
int Obje::instances = 0;
int Obje::getInstances()
{
return instances;
}
Obje::Obje(int auxId)
{
this->id = auxId;
cout << "Obje Created." << endl;
Obje::instances++;
}
Obje::~Obje()
{
cout << "Obje Destroyed." << endl;
Obje::instances--;
}
void Obje::myClass()
{
cout << "Obje." << endl;
}
void Obje::getId()
{
cout << this->id << endl;
}
int main()
{
vector <Obje> list;
Obje *a = new Obje(59565);
list.push_back(*a);
Obje *b = new Obje(15485);
list.push_back(*b);
for(vector<Obje>::iterator it = list.begin(); it != list.end(); ++it)
{
it->getId();
}
return 0;
}
它生成以下输出:
Obje Created.
Obje Created.
Obje Destroyed.
59565
15485
Obje Destroyed.
Obje Destroyed.
我所看到的T(const T& new);
是什么意思?
首先,在堆中分配对象而不使用智能指针并忘记delete
是一种糟糕的做法。尤其是当您创建它只是为了复制它时。
CCD_ 3在向量中创建CCD_ 4的副本。要在矢量中创建一个项而不复制另一个项,可以执行list.emplace_back(/*constructor parameters*/);
,它可从c++11获得。(参见http://en.cppreference.com/w/cpp/container/vector/emplace_back)
因此,为了使结果行为符合您的期望,您应该进行
vector <Obje> vec;
vec.emplace_back(59565);
vec.emplace_back(15485);
for(const auto & item : vec)
{
item.getId();
}
顺便说一句,将向量称为列表也是一种非常糟糕的做法,因为列表是不同的容器类型,读取这样的代码可能会有点混乱。我想,我开始很烦人了,但最好将方法getId
调用为showId
,因为现在它什么都不返回。
关于堆、new和指针的使用,请参阅我在您的问题中的评论。
关于问题对象被销毁,vector
维护一个内部缓冲区来存储对象。当您将push_back
新对象vector
时,如果其内部缓冲区已满,它将(此处不提及异常发生时将执行的内容):
- 分配新的内部缓冲区,该缓冲区足够大以存储其新数据
- 将数据从旧的内部缓冲区移动到新的内部缓冲区时
- 销毁旧缓冲区
因此,在这种情况下,您的对象将被销毁并复制到新位置,因此复制构造函数会让您更清楚。
p/S:AFAIK,一些编译器通过memmove
或std::move
移动数据
相关文章:
- 在不复制临时对象的情况下延长其生存期
- 为什么当我们有常量引用时创建临时对象?
- 程序如何'remember'临时对象?
- 返回对临时对象的引用
- 防止临时对象文件访问 MSVC 中的磁盘
- 是否可以在C++中移动临时对象的属性?
- 通过引用传递临时对象
- 临时C++对象是否为左值?
- 临时对象:术语澄清
- 存储对(可能)临时对象的引用是否合法,只要引用不比对象存活?
- 临时对象有身份吗?
- 临时对象上的运算符重载
- 如何在没有 std::move 的情况下移动临时对象
- 临时对象在C++中是不可避免的吗?
- 编译错误:临时对象构造函数中缺少参数
- 为什么在按值返回时创建临时对象,而不是在按值传递给函数参数时创建临时对象
- 我试图创建临时对象的方式有错误吗
- 子表达式中临时对象的生存期
- 对临时对象的Const引用不会延长其生存期
- 为什么引用类型在使用临时对象访问时是左值