C++ 在C++;,如何将对象推送到向量,同时保持指向该对象的指针?
在我的代码中,我有一个学生对象的向量C++ 在C++;,如何将对象推送到向量,同时保持指向该对象的指针?,c++,pointers,vector,C++,Pointers,Vector,在我的代码中,我有一个学生对象的向量 vector<Student> m_students; 当我打电话给m_学生时,将其向后推(*targetStudent)向量“m_students”似乎以“targetStudent”当时指向的学生对象的副本结束 随后添加到targetStudent的尝试不会更改向量中包含的对象 如何从指向对象的指针开始,将该对象添加到向量,然后访问向量中的对象?STL容器复制它们包含的对象。没有办法解决这个问题 但是,您可以拥有一个std::vector,
vector<Student> m_students;
当我打电话给m_学生时,将其向后推(*targetStudent)代码>向量“m_students”似乎以“targetStudent”当时指向的学生对象的副本结束
随后添加到targetStudent的尝试不会更改向量中包含的对象
如何从指向对象的指针开始,将该对象添加到向量,然后访问向量中的对象?STL容器复制它们包含的对象。没有办法解决这个问题
但是,您可以拥有一个std::vector
,它允许您拥有一个智能指针容器。但是,要使其起作用,您的对象必须在构建时全部附加到共享\u ptr
比如说:
std::vector<std::shared_ptr<Student> > m_students;
std::shared_ptr<Student> targetStudent;
for each (std::shared_ptr<Student> student in m_students)
{
if (student->Name() == strName)
{
targetStudent = student;
break;
}
}
// If the Student didn't exist, add it.
if (!targetStudent)
{
// creates a new Student and attaches it to smart pointer
targetStudent.reset(new Student(strName));
m_students.push_back(targetStudent);
}
std::vector麻省理工大学学生;
std::共享的ptr目标学生;
每个(标准::在麻省理工大学学生中共享的学生)
{
如果(学生->姓名()==strName)
{
targetStudent=学生;
打破
}
}
//如果该学生不存在,请添加它。
如果(!targetStudent)
{
//创建新学员并将其附加到智能指针
targetStudent.reset(新学生(strName));
m_学生。推回(目标学生);
}
std::shared_ptr
在C++11的
头中定义。(在TR1中,您可以使用std::TR1::shared_ptr
)如果您使用的是不带TR1的C++98,或者需要可移植,则可以使用boost::shared_ptr
;从下载。在对象插入向量后获取指向该对象的指针,因此
targetStudent = new Student(strName);
m_students.push_back(*targetStudent);
targetStudent=新学生(strName);
m_学生。推回(*目标学生);
使用
m_学生。推回(学生(strName));
targetStudent=&m_students.back();
还要注意,您的示例会泄漏内存,复制到向量中的targetStudent永远不会被删除
此外,请记住,当添加新元素时,向量中的指针将无效(如果向量的物理大小增加,并且必须将元素复制到新的、更大的向量中,则前一个缓冲区中的所有指针将无效) 你的问题已经得到了一个相当直接的答案。然而,根据你似乎想要实现的目标,在我看来,一个不那么直接的答案可能真的是一个更好的答案
至少当我读到你的描述时,你有很多独特的学生,每个学生都有很多课程。当一个学生完成一门课程时,您需要寻找该学生。如果它们不在集合中,请添加它们。然后添加他们完成的课程的数据
在这种情况下,向量给我的印象是一个不太理想的解。您可以通过两种不同的方式实现代码,但我可能会这样做:
struct course {
std::string Quarter_, Course_, Credits_, Grade_;
using std::string;
course(string const &q, string const &c, string const &cr, string const &g)
: Quarter_(q), Course_(c), Credits_(cr), Grade_(g)
{}
};
std::map<std::string, std::vector<course> > m_students;
回到您最初的问题,标准容器用于处理值。您将一个值传递给它们,它们将存储该值的副本。这样做的一个后果是,像push_back(new XXX)
这样的东西本质上总是一个错误(几乎肯定是内存泄漏)。如果你有一个物体,就把它传过去。如果没有,只需创建一个临时文件并传递它。在Java中(例如),到处看到新的XXX
是一种常规,几乎是不可避免的。虽然你也可以用C++编写这种方法,但这不是你应该期望的规则。我建议在引用标准命名空间时始终使用::STD而不是STD。如果有人将自己的名称空间命名为“std”(当然不是顶级名称,这是不合法的),那么在某些情况下,您可能会得到对std的模糊或意外解析的引用。@Omnifarious有些人还可以定义std foo
。你不能为每一个白痴都做好准备。@quant\u dev:这并不是因为有人可能在另一个名称空间中创建一个名为std
的名称空间。因此,你习惯于用你所指的名字来引用名称空间,而不是今天看来最合适的名字。理论上,你是对的。实际上,惯例是,头脑正常的人不会将std
用于他们的名称空间。这比shared_ptr
提案简单得多,仅出于这个原因就更好了。我刚才重读了这个答案,并同意我也喜欢它+1我也同意MSalters所说的,即使我写了共享\u ptr
答案,如果OP选择了这个答案或Jerry的答案,我也不会有任何问题,这两个答案都很好。:-)+1这实际上非常类似于我在Chris指出容器总是会复制后所做的事情。还感谢您指出内存泄漏(我习惯于垃圾收集语言,不必经常考虑堆。)+1您是对的,这更像我想要的……如果我的目标是创建一个真正的应用程序。不幸的是,这是一个学校作业,教授非常具体地说明了我们应该使用什么样的数据结构,没有空间进行这种创新。
m_students.push_back(Student(strName));
targetStudent = &m_students.back();
struct course {
std::string Quarter_, Course_, Credits_, Grade_;
using std::string;
course(string const &q, string const &c, string const &cr, string const &g)
: Quarter_(q), Course_(c), Credits_(cr), Grade_(g)
{}
};
std::map<std::string, std::vector<course> > m_students;
m_students[strName].push_back(course(strQuarter, strCourse, strCredits, strGrade));