C++ 动态对象数组不工作

C++ 动态对象数组不工作,c++,arrays,C++,Arrays,我有一个父项和两个子项,我想创建一个包含子项的动态数组(不允许使用向量)。我创建了类和所有东西,没有得到编译错误或警告,但是当我尝试访问数组的一个成员并打印其内容时,什么也没有发生 我知道这里可能有一些糟糕的编码风格,但我只想知道为什么数组不能工作。我想这是因为我创建了一个对象数组,而不是指向对象的指针数组,我不确定 (我从代码中删除了第二个子项,因为它与此处无关) #杂注警告(禁用:4996) 使用名称空间std; #包括 #包括 #包括 #包括“date.h” #定义地址\u大小512 #定

我有一个父项和两个子项,我想创建一个包含子项的动态数组(不允许使用向量)。我创建了类和所有东西,没有得到编译错误或警告,但是当我尝试访问数组的一个成员并打印其内容时,什么也没有发生

我知道这里可能有一些糟糕的编码风格,但我只想知道为什么数组不能工作。我想这是因为我创建了一个对象数组,而不是指向对象的指针数组,我不确定

(我从代码中删除了第二个子项,因为它与此处无关)

#杂注警告(禁用:4996)
使用名称空间std;
#包括
#包括
#包括
#包括“date.h”
#定义地址\u大小512
#定义名称\u大小128
#定义日期\u大小128
阶级待遇{
受保护的:
国际治疗协会;
int患者ID;
治疗日期;
国际治疗费用;
公众:
治疗(){}
治疗(int治疗ID、int患者ID、int治疗费用、char治疗日期[日期大小]){
这->治疗ID=治疗ID;
此->患者ID=患者ID;
这->治疗成本=治疗成本;
此->治疗日期。转换治疗日期(治疗日期);
}
无效集处理ID(内部处理ID){
这->治疗ID=治疗ID;
}
无效读取\处理\日期(无效){
治疗日期。读取日期();
}
无效集处理日期(字符日期[日期大小]){
治疗日期。转换日期(\u日期);
}
无效设置患者ID(内部患者ID){
此->患者ID=患者ID;
}
无效设置处理成本(内部处理成本){
这->治疗成本=治疗成本;
}
int get_处理_ID(无效){
返回治疗ID;
}
int获取患者ID(无效){
返回患者ID;
}
int获取治疗成本(无效){
退货处理费用;
}
};
治疗以外的类别:公共治疗{
私人:
国际诊所;
//班主任;
公众:
外部处理(){}
外部治疗(int诊所编号、int治疗编号、int患者编号、int治疗费用、char治疗日期[日期大小]):治疗(治疗编号、患者编号、治疗费用、治疗日期){
此->诊所数量=诊所数量;
}
无效集诊所数量(int诊所数量){
此->诊所数量=诊所数量;
}
int get_clinic_num(){
返回此->诊所编号;
}
无效打印\u外部\u处理(无效){

cout您正在创建一个
Treatment
对象实例数组。因此,您根本无法存储任何派生类型。如果您尝试将派生类型的对象分配给
Treatment
对象

你的直觉是正确的。因为你在处理多态类型,你需要在数组中存储指向对象的指针,而不是实际对象。然后你可以存储指向任何派生类型对象的指针,例如:

class Treatment {
    ...
public:
    ...

    // make the base class destructor virtual so calling
    // 'delete' on a base class pointer will invoke derived
    // destructors. Otherwise, if a derived class has any
    // data members with a non-trivial destructor, you will
    // cause leaking.  When writing polymorphic classes, it
    // is common practice to always define a virtual destructor,
    // just in case...
    //
    virtual ~Treatment() {} // <-- add this
    ..
};

class Dynarray {
private:
    Treatment **pa;
    int length;
    int capacity;

    // prevent copying the array, otherwise you risk
    // memory errors if multiple arrays own the same
    // objects being pointed at and try to free them
    // multiple times. Copying pointers to owned objects
    // is not safe, you need a cloning mechanism to
    // make deep-copies of derived types so a copied
    // array can point to its own objects...
    Dynarray(const Dynarray &) {}
    Dynarray& operator=(const Dynarray &) {}

public:
    Dynarray(int initialCapacity = 10) {
        pa = new Treatment*[initialCapacity];
        capacity = initialCapacity;
        length = 0;
    }

    ~Dynarray() {
        for (int i = 0; i < length; ++i)
            delete pa[i];
        delete[] pa;
    }

    void add(Treatment *add) {
        if (length == capacity) {
            Dynarray temp(capacity + 10);
            for (int i = 0; i < length; ++i) {
                temp.pa[i] = pa[i];
            }
            Treatment *ptr = temp.pa;
            temp.pa = pa;
            pa = ptr;
            capacity = temp.capacity;
        }

        pa[length++] = add;
    }

    Treatment* operator[](int index) {
        return pa[index];
    }
};

int main(void) {
    Outside_treatment *ot = new Outside_treatment;

    cout << "Enter the patient ID\n";
    int p_id;
    cin >> p_id;
    ot->set_patient_ID(p_id);
    cin.ignore();
    cout << "set treatment date\n";
    ot->read_treatment_date();

    cout << "enter costs\n";
    int costs;
    cin >> costs;
    ot->set_treatment_costs(costs);

    cout << "enter section num\n";
    int sc_num;
    cin >> sc_num;
    ot->set_clinic_num(sc_num);

    ot->print_outside_treatment();

    Dynarray da;
    da.add(ot);

    Treatment *t = da[0];

    int i = t->get_patient_ID();
    cout << i << endl;

    while (1);
};

提示:使用
std:vector
而不是
new[]
。这将为您节省大量的痛苦和麻烦。此外,如果您的程序运行不符合您的预期,请使用调试器查看发生了什么。正如我在帖子中所说,我的大学不允许我使用向量。为什么人们坚持教授“C++”课程完全不能教任何有意义的C++?这是荒谬的。就像他们开始使用<代码>使用命名空间STD;< /C> >,这是一个坏习惯,从那里开始急剧下降。我都是从第一原理教东西的,但是即使是Bjarne写的书,也显示了标准库容器是如何运行的。是从原语构建的,它不会重新发明轮子,只是向你展示轮子是如何制造的。希望你能做你必须做的事情来通过。调试器时间到了!啊哈-通常的“不要使用正确的工具来完成任务,而要黑掉一些你永远不会再使用的东西”BS。唯一的理由是如果这是一门试图展示y的课程你有一个
Treatment
数组,你需要搜索的术语是“切片”。
virtual~Treatment(){}//@EdHeal:如果基类析构函数不是
virtual
,在基类指针上调用
delete
将不会调用派生析构函数。只要派生类没有任何具有非平凡析构函数的数据成员,这是可以的。如果有,则需要虚拟析构函数以避免泄漏。在编写多态性类,通常会定义一个虚拟析构函数,以防万一。我熟悉切片,但我只需要访问父方法,所以我认为它在这里不起作用。我复制粘贴了您的代码,但它似乎也没有打印出来。无论如何,您已经修复了足够的虚拟析构函数,我现在可以自己调试了。谢谢。@MichaelX:切片不是about方法,它是关于数据的。如果你切片一个
Outside\u treatment
对象,你就会丢失它的
clinic\u num
数据。那么,首先创建一个
Outside\u treatment
对象是没有意义的。
虚拟get\u clinic\u num()?
class Treatment {
    ...
public:
    ...

    // make the base class destructor virtual so calling
    // 'delete' on a base class pointer will invoke derived
    // destructors. Otherwise, if a derived class has any
    // data members with a non-trivial destructor, you will
    // cause leaking.  When writing polymorphic classes, it
    // is common practice to always define a virtual destructor,
    // just in case...
    //
    virtual ~Treatment() {} // <-- add this
    ..
};

class Dynarray {
private:
    Treatment **pa;
    int length;
    int capacity;

    // prevent copying the array, otherwise you risk
    // memory errors if multiple arrays own the same
    // objects being pointed at and try to free them
    // multiple times. Copying pointers to owned objects
    // is not safe, you need a cloning mechanism to
    // make deep-copies of derived types so a copied
    // array can point to its own objects...
    Dynarray(const Dynarray &) {}
    Dynarray& operator=(const Dynarray &) {}

public:
    Dynarray(int initialCapacity = 10) {
        pa = new Treatment*[initialCapacity];
        capacity = initialCapacity;
        length = 0;
    }

    ~Dynarray() {
        for (int i = 0; i < length; ++i)
            delete pa[i];
        delete[] pa;
    }

    void add(Treatment *add) {
        if (length == capacity) {
            Dynarray temp(capacity + 10);
            for (int i = 0; i < length; ++i) {
                temp.pa[i] = pa[i];
            }
            Treatment *ptr = temp.pa;
            temp.pa = pa;
            pa = ptr;
            capacity = temp.capacity;
        }

        pa[length++] = add;
    }

    Treatment* operator[](int index) {
        return pa[index];
    }
};

int main(void) {
    Outside_treatment *ot = new Outside_treatment;

    cout << "Enter the patient ID\n";
    int p_id;
    cin >> p_id;
    ot->set_patient_ID(p_id);
    cin.ignore();
    cout << "set treatment date\n";
    ot->read_treatment_date();

    cout << "enter costs\n";
    int costs;
    cin >> costs;
    ot->set_treatment_costs(costs);

    cout << "enter section num\n";
    int sc_num;
    cin >> sc_num;
    ot->set_clinic_num(sc_num);

    ot->print_outside_treatment();

    Dynarray da;
    da.add(ot);

    Treatment *t = da[0];

    int i = t->get_patient_ID();
    cout << i << endl;

    while (1);
};
class Dynarray {
private:
    Treatment **pa;
    int length;
    int capacity;

public:
    Dynarray(int initialCapacity = 10) {
        pa = new Treatment*[initialCapacity];
        capacity = initialCapacity;
        length = 0;
    }

    // coping is OK since the objects being pointed
    // at are not owned by the array!
    Dynarray(const Dynarray &src) {
        pa = new Treatment*[src.capacity];
        capacity = src.capacity;
        length = src.length;
        for (int i = 0; i < length; ++i) {
            pa[i] = src.pa[i];
        }
    }

    Dynarray& operator=(const Dynarray &rhs) {
        if (&rhs != this) {
            Dynarray temp(rhs);
            Treatment **ptr = temp.pa;
            temp.pa = pa;
            pa = ptr;
            capacity = rhs.capacity;
            length = rhs.length;
        }
        return *this;
    }

    ~Dynarray() {
        delete[] pa;
    }

    void add(Treatment *add) {
        if (length == capacity) {
            Dynarray temp(capacity + 10);
            for (int i = 0; i < length; ++i) {
                temp.pa[i] = pa[i];
            }
            Treatment **ptr = temp.pa;
            temp.pa = pa;
            pa = ptr;
            capacity = temp.capacity;
        }

        pa[length++] = add;
    }

    Treatment* operator[](int index) {
        return pa[index];
    }
};

int main(void) {
    Outside_treatment ot;

    cout << "Enter the patient ID\n";
    int p_id;
    cin >> p_id;
    ot.set_patient_ID(p_id);
    cin.ignore();
    cout << "set treatment date\n";
    ot.read_treatment_date();

    cout << "enter costs\n";
    int costs;
    cin >> costs;
    ot.set_treatment_costs(costs);

    cout << "enter section num\n";
    int sc_num;
    cin >> sc_num;
    ot.set_clinic_num(sc_num);

    ot.print_outside_treatment();

    Dynarray da;
    da.add(&ot);

    Treatment *t = da[0];

    int i = t->get_patient_ID();
    cout << i << endl;

    while (1);
};