虚析构函数分析,为什么第一个输出是9,第二个输出是2呢?

时间:2022-09-18 11:24:06
有人可以帮我分析一下,下面的代码,为什么第一个输出结果是9,第二个输出结果会是2呢?


#include <iostream.h>

static int x;
class A
{
public:
A(){ cout<<"AA1"<<endl; x = 1; }
virtual ~A(){ cout<<"~A2"<<endl; x = 2; }
virtual void foo(){ cout<<"A::foo()A3"<<endl; x = 3;}
};

class B : public A
{
public:
B(){ cout<<"BB4"<<endl; x = 4; }
virtual ~B(){ cout<<"~B5"<<endl; x = 5; }
void foo(){ cout<<"B::foo()B6"<<endl; x = 6; }
void bar(){ cout<<"B::bar()"<<endl; foo(); }
};

class C : public B
{
public:
C(){ cout<<"CC7"<<endl;x = 7; }
virtual ~C(){ cout<<"~C8"<<endl; x = 8; }
void foo(){ cout<<"C::foo()C9"<<endl; x = 9 ;}
void bar(){ cout<<"C::bar()"<<endl; foo(); }
};



int main(void)
{
C testc;

testc.foo();
cout<<"1------------------------------------  "<< x<<endl;
((C)testc).foo();
cout<<"2------------------------------------  "<< x<<endl;
}

14 个解决方案

#1


因为调用了两次析构,资料详解:
http://blog.csdn.net/kevinzhangyang/article/details/6638479

因为都是从A派生过来的,你在A的析构里面设置为了2所以是2

#2


为什么做了类型转换后,会调用到析构函数呢?

#3


http://dev.yesky.com/145/2206145.shtml

#4


引用 2 楼 wang0921jun 的回复:
为什么做了类型转换后,会调用到析构函数呢?

编译器给你new了一个临时对象了。仔细看下文章。

#5


((C)testc).foo();
copy is made

#6


虚析构函数分析,为什么第一个输出是9,第二个输出是2呢?

#7


不知道斑猪怎么忍受的了这种代码格式

#8


楼主的排版如果不是为了在此处贴代码而有意这样排版,

那么代码风格实在是太糟糕了。

顺便说一下,在C++代码里面建议使用
<iostream>而不是<iostream.h>

引用 楼主 wang0921jun 的回复:
有人可以帮我分析一下,下面的代码,为什么第一个输出结果是9,第二个输出结果会是2呢?


#include <iostream.h>

static int x;
class A
{
public:
A(){ cout<<"AA1"<<endl; x = 1; }
virtual ~A(){ cout<<"~A2"<<endl; x = 2; }
virtual void foo(){ cout<<"A::foo()A3"<<endl; x = 3;}
};

class B : public A
{
public:
B(){ cout<<"BB4"<<endl; x = 4; }
virtual ~B(){ cout<<"~B5"<<endl; x = 5; }
void foo(){ cout<<"B::foo()B6"<<endl; x = 6; }
void bar(){ cout<<"B::bar()"<<endl; foo(); }
};

class C : public B
{
public:
C(){ cout<<"CC7"<<endl;x = 7; }
virtual ~C(){ cout<<"~C8"<<endl; x = 8; }
void foo(){ cout<<"C::foo()C9"<<endl; x = 9 ;}
void bar(){ cout<<"C::bar()"<<endl; foo(); }
};



int main(void)
{
C testc;

testc.foo();
cout<<"1------------------------------------  "<< x<<endl;
((C)testc).foo();
cout<<"2------------------------------------  "<< x<<endl;
}

#9


AA1
BB4
CC7
C::foo()C9
1------------------------------------  9
C::foo()C9
~C8
~B5
~A2
2------------------------------------  2
~C8
~B5
~A2

#10


add copy constructor, made it more clear:
static int x;
class A
{
public:
    A()
    {
        cout<<"AA1"<<endl;
        x = 1;
    }
    A(const A& a)
    {
        cout << "A copy constructor loaded" << endl;
        *this = a;
        x = 11;
    }
    virtual ~A()
    {
        cout<<"~A2"<<endl;
        x = 2;
    }
    virtual void foo()
    {
        cout<<"A::foo()A3"<<endl;
        x = 3;
    }
};

class B : public A
{
public:
    B()
    {
        cout<<"BB4"<<endl;
        x = 4;
    }
    B(const B& b)
    {
        cout << "B copy constructor loaded" << endl;
        *this = b;
        x = 12;
    }
    virtual ~B()
    {
        cout<<"~B5"<<endl;
        x = 5;
    }
    void foo()
    {
        cout<<"B::foo()B6"<<endl;
        x = 6;
    }
    void bar()
    {
        cout<<"B::bar()"<<endl;
        foo();
    }
};

class C : public B
{
public:
    C()
    {
        cout<<"CC7"<<endl;
        x = 7;
    }
    C(const C& c)
    {
        cout << "C copy constructor loaded" << endl;
        *this = c;
        x = 13;
    }
    virtual ~C()
    {
        cout<<"~C8"<<endl;
        x = 8;
    }
    void foo()
    {
        cout<<"C::foo()C9"<<endl;
        x = 9 ;
    }
    void bar()
    {
        cout<<"C::bar()"<<endl;
        foo();
    }
};



int main(void)
{
    C testc;

    testc.foo();
    cout<<"1------------------------------------  "<< x<<endl;
    ((C)testc).foo();
    cout<<"2------------------------------------  "<< x<<endl;
}


result:
AA1
BB4
CC7
C::foo()C9
1------------------------------------  9
AA1
BB4
C copy constructor loaded
C::foo()C9
~C8
~B5
~A2

2------------------------------------  2
~C8
~B5
~A2

Process returned 0 (0x0)   execution time : 0.002 s
Press ENTER to continue.

#11


引用 7 楼 u013685578 的回复:
不知道斑猪怎么忍受的了这种代码格式

谢谢你的回复。我是在Linux下编辑的,粘贴过来就成了这个样子。
不过我还是不太懂具体的原理。

#12


引用 10 楼 buyong 的回复:
add copy constructor, made it more clear:
[code=c]
1------------------------------------  9
AA1
BB4
C copy constructor loaded
C::foo()C9
~C8
~B5
~A2

2------------------------------------  2
~C8
~B5
~A2

Process returned 0 (0x0)   execution time : 0.002 s
Press ENTER to continue.


为什么在执行了C::foo()函数后,会调用到析构函数呢?

#13


引用 5 楼 mujiok2003 的回复:
((C)testc).foo();
copy is made


临时对象会被析构, 析构至~A()时, x=2

#14


10楼正解啊!
在你((C)testc).foo();的时候,其实调用了系统默认的拷贝构造函数,生成了一个临时对象来调用foo(),所以调用完foo后,调用了析够函数。
学习了。

#1


因为调用了两次析构,资料详解:
http://blog.csdn.net/kevinzhangyang/article/details/6638479

因为都是从A派生过来的,你在A的析构里面设置为了2所以是2

#2


为什么做了类型转换后,会调用到析构函数呢?

#3


http://dev.yesky.com/145/2206145.shtml

#4


引用 2 楼 wang0921jun 的回复:
为什么做了类型转换后,会调用到析构函数呢?

编译器给你new了一个临时对象了。仔细看下文章。

#5


((C)testc).foo();
copy is made

#6


虚析构函数分析,为什么第一个输出是9,第二个输出是2呢?

#7


不知道斑猪怎么忍受的了这种代码格式

#8


楼主的排版如果不是为了在此处贴代码而有意这样排版,

那么代码风格实在是太糟糕了。

顺便说一下,在C++代码里面建议使用
<iostream>而不是<iostream.h>

引用 楼主 wang0921jun 的回复:
有人可以帮我分析一下,下面的代码,为什么第一个输出结果是9,第二个输出结果会是2呢?


#include <iostream.h>

static int x;
class A
{
public:
A(){ cout<<"AA1"<<endl; x = 1; }
virtual ~A(){ cout<<"~A2"<<endl; x = 2; }
virtual void foo(){ cout<<"A::foo()A3"<<endl; x = 3;}
};

class B : public A
{
public:
B(){ cout<<"BB4"<<endl; x = 4; }
virtual ~B(){ cout<<"~B5"<<endl; x = 5; }
void foo(){ cout<<"B::foo()B6"<<endl; x = 6; }
void bar(){ cout<<"B::bar()"<<endl; foo(); }
};

class C : public B
{
public:
C(){ cout<<"CC7"<<endl;x = 7; }
virtual ~C(){ cout<<"~C8"<<endl; x = 8; }
void foo(){ cout<<"C::foo()C9"<<endl; x = 9 ;}
void bar(){ cout<<"C::bar()"<<endl; foo(); }
};



int main(void)
{
C testc;

testc.foo();
cout<<"1------------------------------------  "<< x<<endl;
((C)testc).foo();
cout<<"2------------------------------------  "<< x<<endl;
}

#9


AA1
BB4
CC7
C::foo()C9
1------------------------------------  9
C::foo()C9
~C8
~B5
~A2
2------------------------------------  2
~C8
~B5
~A2

#10


add copy constructor, made it more clear:
static int x;
class A
{
public:
    A()
    {
        cout<<"AA1"<<endl;
        x = 1;
    }
    A(const A& a)
    {
        cout << "A copy constructor loaded" << endl;
        *this = a;
        x = 11;
    }
    virtual ~A()
    {
        cout<<"~A2"<<endl;
        x = 2;
    }
    virtual void foo()
    {
        cout<<"A::foo()A3"<<endl;
        x = 3;
    }
};

class B : public A
{
public:
    B()
    {
        cout<<"BB4"<<endl;
        x = 4;
    }
    B(const B& b)
    {
        cout << "B copy constructor loaded" << endl;
        *this = b;
        x = 12;
    }
    virtual ~B()
    {
        cout<<"~B5"<<endl;
        x = 5;
    }
    void foo()
    {
        cout<<"B::foo()B6"<<endl;
        x = 6;
    }
    void bar()
    {
        cout<<"B::bar()"<<endl;
        foo();
    }
};

class C : public B
{
public:
    C()
    {
        cout<<"CC7"<<endl;
        x = 7;
    }
    C(const C& c)
    {
        cout << "C copy constructor loaded" << endl;
        *this = c;
        x = 13;
    }
    virtual ~C()
    {
        cout<<"~C8"<<endl;
        x = 8;
    }
    void foo()
    {
        cout<<"C::foo()C9"<<endl;
        x = 9 ;
    }
    void bar()
    {
        cout<<"C::bar()"<<endl;
        foo();
    }
};



int main(void)
{
    C testc;

    testc.foo();
    cout<<"1------------------------------------  "<< x<<endl;
    ((C)testc).foo();
    cout<<"2------------------------------------  "<< x<<endl;
}


result:
AA1
BB4
CC7
C::foo()C9
1------------------------------------  9
AA1
BB4
C copy constructor loaded
C::foo()C9
~C8
~B5
~A2

2------------------------------------  2
~C8
~B5
~A2

Process returned 0 (0x0)   execution time : 0.002 s
Press ENTER to continue.

#11


引用 7 楼 u013685578 的回复:
不知道斑猪怎么忍受的了这种代码格式

谢谢你的回复。我是在Linux下编辑的,粘贴过来就成了这个样子。
不过我还是不太懂具体的原理。

#12


引用 10 楼 buyong 的回复:
add copy constructor, made it more clear:
[code=c]
1------------------------------------  9
AA1
BB4
C copy constructor loaded
C::foo()C9
~C8
~B5
~A2

2------------------------------------  2
~C8
~B5
~A2

Process returned 0 (0x0)   execution time : 0.002 s
Press ENTER to continue.


为什么在执行了C::foo()函数后,会调用到析构函数呢?

#13


引用 5 楼 mujiok2003 的回复:
((C)testc).foo();
copy is made


临时对象会被析构, 析构至~A()时, x=2

#14


10楼正解啊!
在你((C)testc).foo();的时候,其实调用了系统默认的拷贝构造函数,生成了一个临时对象来调用foo(),所以调用完foo后,调用了析够函数。
学习了。