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