2017-08-01 77 views
0

我不认为有任何问题指出我要找的解释。通过引用传递C++,指针的向量。这里发生了什么?

在此示例中(ABC类中的tryme()函数),为什么在创建对象时将执行父级的myfunction,并将其引用直接作为参数分配给该函数。

class parent 
{ 
public: 
     int abc; 
     parent(){}; 
     ~parent(){}; 
     virtual void myfunction(void) 
     { 
      abc = 5; 
      output("parent myfunction abc %d", abc); 
     }; 
}; 

class child :public parent 
{ 

public: 
    int abc; 
    child(int val):abc(val){}; 
    child(){}; 
    ~child(){}; 

    virtual void myfunction(void) 
    { 
     output("child myfunction abc %d", abc); 
    } 
}; 

class ABC 
{ 
     std::vector<parent *> pvec; 
     void test(parent* t) 
     { 
      pvec.pushback(t); 
     }; 

     void tryme() 
     { 
      child c1 = child(3); 
      child c2 = child(6); 

      ABC::test(&c1); <-------- this executed child - I understand 
      ABC::test(&c2); <-------- this executed child - I understand 
      ABC::test(&child(9)); <-------- this executed parent - I dont understand 
      ABC::test(&child(11));<-------- this executed parent - I dont understand 

      for each (auto it in pvec) 
      { 
        it->myfunction(); 
      } 
     } 
} 

输出

child myfunction abc 3 
    child myfunction abc 6 
    parent myfunction abc 5 
    parent myfunction abc 5 

是什么 child c1 = child(3); &c1;

&child(3)

感谢

之间的不同
+7

'test(&child(9));'会将一个悬挂指针存储到临时'child'对象,该对象在'test'返回后被销毁。所以你在这里面对UB。 – VTT

+2

c1和c2并不好多少​​。 – 2017-08-01 22:28:15

+0

你确定它被执行了吗?我可以在xcode ABC :: test(&child(9))中看到警告; //获取类型为“child”的临时对象的对象 –

回答

1

有几件事......你的头衔表明你是“通过引用传递”。事实上,你正在传递“通过指针”。

而且,当你调用

ABC::test(&c1); 

你把你的堆栈变量c1的地址,并把它传递给你的函数。您的数组然后存储对象的地址。前两个电话是可以的。

但是......当你打电话

ABC::test(&child(9)); 

您正在创建一个临时对象,将只适用于函数调用的持续时间和通过其地址的功能,然后存储一个“悬空“指向临时对象的指针。

当函数调用结束时,对象被销毁。由数组仍然保持指向现在的垃圾内存。

稍后它调用“父”函数调用的事实是完全随机的,未定义的行为。它可以很容易地打印出生活的意义,或者在过去的日子里,您的显示器被炸了。 :)

+0

哈哈..谢谢,我不确定我会理解生活的意义,但是我确定我明白了这里的问题。再次感谢。 – legameeternoforall