mw 发帖数: 525 | 1 为什么member的constustrctor会比class constructor先调用,奇怪啊
下面code的输出居然是a c b,不解,望赐教
#include
#include
using namespace std;
class a{
public:
a(){cout<<"a"<
};
class c{
public:
c(){cout<<"c"<
};
class b: public a{
public:
b(){cout<<"b"<
c instc;
};
int main(int argc, char *argv[])
{
system("PAUSE");
b instb;
return EXIT_SUCCESS;
} |
w***g 发帖数: 5958 | 2 你怎么知道cout << "b" << endl; 是b()做的第一件事?
正确的理解是b()在调用cout << "b" << endl;之前先调用了a(), 然后逐个调用
member constructor。这些东西可以在b()的初始化列表中显式指定,但不要认为你不
给初始化列表它们就不在了。弄完这些b()才开始执行函数体里你给出的代码。
真正的顺序是b a c。
【在 mw 的大作中提到】 : 为什么member的constustrctor会比class constructor先调用,奇怪啊 : 下面code的输出居然是a c b,不解,望赐教 : #include : #include : using namespace std; : class a{ : public: : a(){cout<<"a"<: }; : class c{
|
h***z 发帖数: 233 | 3 You must first create the parts before you can build the whole thing.
【在 mw 的大作中提到】 : 为什么member的constustrctor会比class constructor先调用,奇怪啊 : 下面code的输出居然是a c b,不解,望赐教 : #include : #include : using namespace std; : class a{ : public: : a(){cout<<"a"<: }; : class c{
|
s***e 发帖数: 122 | 4 前面都很同意,只是怎么结论给的很诡异呢?
【在 w***g 的大作中提到】 : 你怎么知道cout << "b" << endl; 是b()做的第一件事? : 正确的理解是b()在调用cout << "b" << endl;之前先调用了a(), 然后逐个调用 : member constructor。这些东西可以在b()的初始化列表中显式指定,但不要认为你不 : 给初始化列表它们就不在了。弄完这些b()才开始执行函数体里你给出的代码。 : 真正的顺序是b a c。
|
w***g 发帖数: 5958 | 5 函数执行的顺序是b a c,但是输出的是 a c b。编译器生成的b()的代码应该对应的是
b()
{
a(); //自动加入
c(); //自动加入
cout << "b" << endl;
}
所以调用b()时反而先输出了a c。
如果认为自动加入那部分不是构造函数的一部分,那么得出的执行顺序应该是a c b,
但是我觉得这么理解不妥。
【在 s***e 的大作中提到】 : 前面都很同意,只是怎么结论给的很诡异呢?
|
s***e 发帖数: 122 | 6 现在明白了,呵呵,怎么说来着,it's more than clear now.
主要是我们如果用顺序的方式去解释,就没法反映其中的层次。而把compiler生成的整个函数体写出来之后,就清晰多了。
刚才很有兴趣的用Java也测试了一下,发现结果是一样的。不过把virtual函数放到constructor之后就有不同的效果了。
C++输出是:
a
a.f()
c
b
Java输出是:
a
b.f()
c
b
// =========== C++ Implementation ===========
#include
#include
using namespace std;
class a{
public:
a(){cout<<"a"<
virtual f() {cout<<"a.f()"<
};
class c{
public:
c(){cout<<"c"<
};
class b: public a {
public:
b(){cout<<"b"<
virtual f() {c
【在 w***g 的大作中提到】 : 函数执行的顺序是b a c,但是输出的是 a c b。编译器生成的b()的代码应该对应的是 : b() : { : a(); //自动加入 : c(); //自动加入 : cout << "b" << endl; : } : 所以调用b()时反而先输出了a c。 : 如果认为自动加入那部分不是构造函数的一部分,那么得出的执行顺序应该是a c b, : 但是我觉得这么理解不妥。
|
K*****n 发帖数: 65 | 7 If you debug into disassembly, you will see that
a constructor and c constructor are inserted in the front of b constructor
body. That is why you get a, c, b.
class b: public a{
public:
b(){cout<<"b"<
004117C0 push ebp
004117C1 mov ebp,esp
004117C3 sub esp,0CCh
004117C9 push ebx
004117CA push esi
004117CB push edi
004117CC push ecx
004117CD lea edi,[ebp-0CCh]
004117D3 mov ecx,33h
004117D8 mov eax,0CC |
O*******d 发帖数: 20343 | 8 The sequence of call is b(), a(), c(). a() and c() are called before line
cout<<"b"<
followed by cout << "b" |
h***z 发帖数: 233 | 9 You can interpret it that way, though I think the more common interpretation
is that a and c are constructed automatically before b() is called.
【在 w***g 的大作中提到】 : 函数执行的顺序是b a c,但是输出的是 a c b。编译器生成的b()的代码应该对应的是 : b() : { : a(); //自动加入 : c(); //自动加入 : cout << "b" << endl; : } : 所以调用b()时反而先输出了a c。 : 如果认为自动加入那部分不是构造函数的一部分,那么得出的执行顺序应该是a c b, : 但是我觉得这么理解不妥。
|
n**d 发帖数: 9764 | 10 What is the reason that C++ and Java call different f()?
整个函数体写出来之后,就清晰多了。
constructor之后就有不同的效果了。
【在 s***e 的大作中提到】 : 现在明白了,呵呵,怎么说来着,it's more than clear now. : 主要是我们如果用顺序的方式去解释,就没法反映其中的层次。而把compiler生成的整个函数体写出来之后,就清晰多了。 : 刚才很有兴趣的用Java也测试了一下,发现结果是一样的。不过把virtual函数放到constructor之后就有不同的效果了。 : C++输出是: : a : a.f() : c : b : Java输出是: : a
|
t****t 发帖数: 6806 | 11 我前两天没注意到这个贴. java怎样我是不知道, C++里在constructor或destructor里
调用virtual function 是undefined
整个函数体写出来之后,就清晰多了。
constructor之后就有不同的效果了。
【在 s***e 的大作中提到】 : 现在明白了,呵呵,怎么说来着,it's more than clear now. : 主要是我们如果用顺序的方式去解释,就没法反映其中的层次。而把compiler生成的整个函数体写出来之后,就清晰多了。 : 刚才很有兴趣的用Java也测试了一下,发现结果是一样的。不过把virtual函数放到constructor之后就有不同的效果了。 : C++输出是: : a : a.f() : c : b : Java输出是: : a
|