Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C++;,如何将对象推送到向量,同时保持指向该对象的指针?_C++_Pointers_Vector - Fatal编程技术网

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));