我有一项任务是创建一个对象 Stos ,其中包含一堆对象 Obiekt ,我可以随意添加对象。
为了使程序更好地支持动态数组,我决定使用Vector。 整个实现似乎完美运行,返回值完全关闭。 以下是代码示例:
class Obiekt {
private:
int id;
public:
Obiekt::Obiekt(int i) {
id = i;
}
void Obiekt::display() {
cout << "This object has id of: " << id << endl;
}
};
class Stos {
private:
vector < Obiekt* > stos;
public:
Stos::Stos(Obiekt n) {
add(n);
}
void Stos::add(Obiekt n) {
stos.push_back(&n);
}
void Stos::display() {
cout << endl << "===HEAP DISPLAY===" << endl;
for (int i = 0; i < stos.size(); i++) {
stos[i]->display();
}
}
};
void Zad1()
{
Obiekt obj1(5);
Obiekt obj2(23);
Stos s1(obj1);
s1.add(obj2);
s1.display();
getchar();
}
结果是:
=== HEAP DISPLAY ===
此对象的ID为:-858993460
此对象的ID为:9805925
我不是cpp专家,并且认为该问题与stos.push_back(&n)
部分有关,但我无法抓住id变得如此扭曲的那一刻。
这可能是一个菜鸟问题,所以很抱歉在开始时。
任何帮助都会很棒。
答案 0 :(得分:3)
正如O'Neil正确解释的那样,您的代码问题是您正在添加指向Obiekt对象的副本的指针。所以基本上,你在main中创建你的对象,并将它传递给Stos中的构造函数和.add函数。然后,将指针添加到矢量。当函数完成时,传递的副本将被销毁,向量中的指针将悬空。 有两种方法可以解决这个问题:
这很简单,基本上你只需在函数参数中添加一个&符号。例如:
void Stos::add(Obiekt &n) {
stos.push_back(&n);
}
这将确保在函数结束时不销毁对象
让问题发挥作用的另一种方法是避免使用指针。您的矢量实际上会将Obiekt对象的内容复制到其中。例如:
vector < Obiekt > stos; // notice how we define it without the pointer type
...
void Stos::add(Obiekt n) {
stos.push_back(n); // Creates copy which will then contain the correct value
}
答案 1 :(得分:1)
中的参数
Obiekt n
Stos::Stos(Obiekt n) {
add(n);
}
void Stos::add(Obiekt n) {
stos.push_back(&n);
}
是每次通话后立即销毁的临时副本。
您必须改为使用引用Obiekt & n
,或者更好:使用指针Obiekt * n
。
答案 2 :(得分:0)
我不愿断言在调用显示器时存在对象。
根据海湾合作委员会的实施情况,他们不会这样做。 它们超出范围并立即被破坏。给&#34; Obiekt&#34;一个非平凡的析构函数,这种行为变得很明显:
~Obiekt(){std::cout << "Bye from: " << it << std::endl;}
其次,请注意,您不应该为类本身定义的函数指定类成员资格(没有class_name :: function_name(参数),只有function_name(参数))
你(可能)想要改变&#34; Stos&#34;这样:
Stos(Obiekt &n) {add(n);}
void add(Obiekt &n) {stos.push_back(&n);}