将对象推回向量指针,对象类进入命名空间

Posted

技术标签:

【中文标题】将对象推回向量指针,对象类进入命名空间【英文标题】:Push back object to vector pointer, class of object is into namespace 【发布时间】:2020-08-20 07:03:40 【问题描述】:

主要问题是如何将患者对象添加到指针向量中。 类 Patient 位于命名空间 Health 中。患者有姓名、姓氏和号码(我使用了 set 和 get)。我应该给医院的指针向量。

主要部分

vector<Health::Patient*> patients;

Health::Patient p1("John", "April");
p1.set("1234");

cout<<p1.get();

Health::Patient p2("George", "Best");
p1.set("2351");

patients.push_back(p1); // in this line push_back doesn't work

Hospital h1("DontGoThere", patients);

我应该创建一个新函数来将患者对象添加到向量中吗?

【问题讨论】:

你想要vector&lt;Health::Patient&gt; patients;(没有星号)。 如果你真的想要 patients 持有指向 Patient 的指针,你还需要 p1 是那种类型:Health::Patient* p1 = new Health::Patient("John", "April"); 但你需要在从向量中弹出元素时显式释放内存这样做 @Momo 你需要叫它p1-&gt;set("2351")。但是考虑不要像@PaulSanders 建议的那样使用指针向量 - 你不必那么关心内存管理。然后你需要调整Hospital的构造函数,例如Hospital::Hospital(std::string str, std::vector&lt;Health::Patient&gt; &amp;patients) 任务是使用指针 那么任务就错了。 任务是教你bad C++。 【参考方案1】:

一些不同的方法:

    patients 保留为Health::Patient* 的向量

    std::vector<Healt::Patient*> patients;
    Health::Patient *p1 = new Health::Patient("John", "April");
    p1->set("1234");
    

    这样,您必须注意为每个 Patient 实例分配的内存将被正确释放,例如:

    // delete last container element
    std::vector<Health::Patient*>::iterator itr = patients.back();
    
    if (*itr) 
        delete *itr;
    
    
    patients.pop_back(); 
    

    如果一个实例 Hospital 例如,这会变得非常混乱。还持有一个指向Patient的已释放实例的指针

    像 1) 你将指针存储在向量中,但不在堆上分配 Patient 实例:

    std::vector<Healt::Patient*> patients;
    Health::Patient p1 ("John", "April");
    p1.set("1234");
    patients.push_back(&p1);
    

    这带来了patients 可能超出范围但您仍然取消引用传递给Hospital 实例的指针的风险

    不要使用存储对象指针的向量:

    vector<Health::Patient> patients;
    
    Health::Patient p1("John", "April");
    p1.set("1234");
    
    patients.push_back(p1);
    
    // adjust Constructor of `Hospital` so it takes `std::vector<Patient>`
    // as argument (or a reference to it)
    

    这里的好处是你可以简单地调用patients.pop_back() 来删除最后一个元素——不需要释放你在堆上分配的内存。当向量超出范围时,内存会自动释放。

在不知道您的整个代码的情况下,我建议Hospital 拥有Patient 的实际实例(或副本),并且您直接将对象添加到那里,而无需本地容器,而是作为Hospital 的成员(尤其是如果它是一个指针容器)

void Hospital::addPatient(Health::Patient p) 
   m_patients.push_back(p);


Health::Patient p1("John", "April");
p1.set("1234");
h1.addPatient(p1); 

编辑:当坚持使用指针时

对于指针方法,您应该确保 Hospital 拥有传递的 Patient 实例的所有权,因此仅在此处处理内存管理:

// m_patients now of type std::vector<Health::Patient*>
void Hospital::addPatient(Health::Patient* p) 
   if (p) 
        m_patients.push_back(p);
   


Health::Patient *p1 = new Health::Patient("John", "April");
p1->set("1234");

// Hospital takes ownership
h1.addPatient(p1);
p1 = NULL;

对于这种方法,最好不要使用指针变量p1,并改进Patient 的构造函数,以便它立即创建正确的对象,而您不必确保p1不能再访问了。

h1.addPatient(new Health::Patient("John", "April", "1234"));

如 1) 所示,您需要确保正确释放内存 - Hospital 的析构函数将是释放 m_patients 中所有剩余元素的正确位置,例如

【讨论】:

以上是关于将对象推回向量指针,对象类进入命名空间的主要内容,如果未能解决你的问题,请参考以下文章

C ++在boost python中使用带有命名空间的自定义智能指针

Python()-类命名空间和对象/实例命名空间

python基础 13 类命名空间于对象实例的命名空间,组合方法

类命名空间与对象实例的命名空间

类命名空间与对象实例的命名空间 and 面向对象的组合用法

20180724 (面向对象:类的命名空间和查询顺序丶组合)