• 欢迎浏览“String me = Creater\忠实的资深Linux玩家;”,请文明浏览,理性发言,有侵犯你的权益请邮件我(creater@vip.qq.com).
  • 把任何的失败都当作一次尝试,不要自卑;把所有的成功都想成是一种幸运,不要自傲。
  •    6年前 (2013-04-11)  C++ |   抢沙发  11 
    文章评分 0 次,平均分 0.0

    还是先上代码

    #include <iostream>
    using namespace std;
    
    class A
    {
    public:
        A(int j):i(j)
        {
            fun1();           //在构造函数中调用了虚函数
        }
        ~A()
        {
        }
        void fun1()
           {
               i *= 10;
               fun2();
           }
        int getValue(){
        	return i;
        }
    protected:
        virtual void fun2()
        {
            i++;
        }
    private:
        int i;
    };
    
    class B:public A
    {
    public:
        B(int j):A(j)
        {
        }
        virtual ~B()
        {
        }
        void fun1()
          {
              i *= 100;
              fun2();
          }
    protected:
        void fun2()
        {
            i += 2;
        }
    private:
        int i;
    };
    int main()
    {
         A* p = new B(1);
         cout<<p->getValue()<<endl;
         delete p;
         return 0;
    };


    你看来答案是多少呢?反正我是算错了,但是我搞清了原因,争取下一次不出错。“答案是11”.

    先来看看执行顺序。首先 new B(1)-->B的构造函数 --->B的构造函数返回
    -->A的构造函数-->A的func1-->A的func2--->A的构造函数返回-->
    问题1:A的构造函数调用的是基类的func1,func2,而不锁派生类中的。因为A在构造的时候,B的对象还没构造完成,所以还不能动态绑定。所以A的构造函数结束后,A类对象的i值为11,B对象的i的值为0.
    问题2:getValue返回谁的i? 应该是返回基类的i,因为getvalue不是虚函数,不动态绑定。

    来看看调试步骤:
    在B类中,有
    (gdb) p &i
    $2 = (int *) 0x804a010
    (gdb) p i
    $3 = 0
    在A类构造函数完成后
    (gdb) p &i
    $5 = (int *) 0x804a00c
    (gdb) p i
    $6 = 11

    可以看出,A,B类使用的是不同的i。

    #include <iostream>
    using namespace std;
    
    class A
    {
    public:
        A(int j):i(j)
        {
            fun1();           //在构造函数中调用了虚函数
        }
        ~A()
        {
        }
        void fun1()
           {
               i *= 10;
               fun2();
           }
        virtual int getValue(){
        	return i;
        }
    protected:
        virtual void fun2()
        {
            i++;
        }
    private:
        int i;
    };
    
    class B:public A
    {
    public:
        B(int j):A(j)
        {
        }
        virtual ~B()
        {
        }
        virtual int getValue(){
        	return i;
        }
        void fun1()
          {
              i *= 100;
              fun2();
          }
    protected:
        void fun2()
        {
            i += 2;
        }
    private:
        int i;
    };
    int main()
    {
         A* p = new B(1);
         cout<<p->getValue()<<endl;
         delete p;
         return 0;
    };

    这样的结果则是0。
    可以参考《effective c++》

    所以不要在构造函数中调用虚函数,他不会多态的。 要区分基类还是派生类。

     

    除特别注明外,本站所有文章均为String me = "Creater\忠实的资深Linux玩家";原创,转载请注明出处来自http://unix8.net/home.php/555.html

    关于

    发表评论

    暂无评论

    切换注册

    登录

    忘记密码 ?

    切换登录

    注册

    扫一扫二维码分享