关于类的简单跟踪的实践

时间:2014-02-28 09:34:21

标签: c++ garbage-collection

我目前正在参加考试的练习考试。我有一个问题,为什么输出就是它。

以下是代码:

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.什么都不应该打印,对吗?

然后是increaseNumber2(q);叫做。但我们传递了地址。这个参数和之前的函数调用有什么区别?无论如何,这应该将q更新为16。

然后删除q.getV()函数。我们无法再访问私有字段。

返回0。

现在堆栈调用删除了对象,因此调用了析构函数。所以打印11,垃圾,15。

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

不是

5   6   garbage  15   11   garbage  15

任何人都能帮助我,指出我的想法是错的?谢谢。

1 个答案:

答案 0 :(得分:0)

  

现在p对象的* v等于15.什么都不应该打印,对吗?

参数按值传递到increaseNumber1。这意味着(以外行人的名义)创建了p的副本,increaseNumber1在此副本上运行。在函数结束时,副本被销毁,调用析构函数打印15

  

然后是increaseNumber2(q);叫做。但我们传递了地址。这个参数和之前的函数调用有什么区别?

参数未复制到函数中。 increaseNumber2在来自呼叫方的q上运行。因此,它不会在功能结束时被销毁,也不会打印任何内容。

  

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