用类进行简单跟踪的练习

Practice on Simple Tracing With Classes

本文关键字:跟踪 练习 简单      更新时间:2023-10-16

我目前正在为一项考试进行练习测试。我有一个问题,为什么输出是这样的。

这是代码:

class Number
{
private:
int *v;
public:
Number(int *addr)
{
v = new int;
*v = *addr;
cout << *v << "   ";
}
int *getV() { return v;}
void setV(int num) {*v = num;}
~Number()
{
cout << *v << "   ";
}
};

===

void increaseNumber1(Number p);
void increaseNumber2(Number &p);
int main()
{
int num1 = 5, num2 = 6, *ptr;
ptr = new int;
Number p(&num1);
Number q(&num2);
Number r(ptr);
r.setV(11);
increaseNumber1(p); 
increaseNumber2(q); 
delete q.getV();
return 0;
}
void increaseNumber1(Number p)
{
int i = *(p.getV());
i = i + 10;
p.setV(i);
}
void increaseNumber2(Number &p)
{
int i = *(p.getV());
i = i + 10;
p.setV(i);
}

假设输出为:5 6 garbage 15 11 garbage 15

这是我的思考过程。首先,我们制作一个Number对象"p"。这将其Number*v值设置为5。所以它打印5。到目前为止还可以。

其次,我们制作一个Number对象"q"。这将其Number*v值设置为6,并打印出6。到目前为止还可以。

然后创建一个Number对象"r",但它是一个具有垃圾值的指针,因为它只保存已分配的地址。所以它打印一个"垃圾"值。到目前为止还可以。

现在我纠结于为什么要印15。调用increaseNumber1(p);时;,它传入Number p对象。自5+10起将*v更新为15。现在p对象的*v等于15。不应该打印任何内容,对吗?

然后增加数字2(q);被调用。但我们把地址传了进来。这个参数和前面的函数调用有什么区别?无论如何,这应该将q更新为16。

然后删除q.getV()函数。我们再也无法进入私人领域。

返回0。

现在堆栈调用移除对象,从而调用析构函数。所以打印11,垃圾,15。

所以我认为是5 6 garbage 11 garbage 15

不是

5   6   garbage  15   11   garbage  15

有谁能帮我指出我的想法错在哪里吗?非常感谢。

现在p对象的*v等于15。不应该打印任何内容,对吗?

参数按值传递到increaseNumber1。这意味着(用外行的话来说)创建了p的副本,并且increaseNumber1对该副本进行操作。在函数结束时,副本被销毁,调用用于打印15的析构函数。

然后增加Number2(q);被调用。但我们把地址传了进来。这个参数和前面的函数调用有什么区别?

参数不会复制到函数中。CCD_ 7对来自呼叫者的CCD_。因此,它不会在函数结束时被销毁,也不会打印任何内容。

无论如何,这应该将q更新为16。

是。