64,670
社区成员
发帖
与我相关
我的任务
分享
#include <iostream>
using namespace std;
class A
{
public:
A (int aa = 0) : a(aa)
{
cout << "call A ()" << endl;
}
private:
int a;
};
class B : public A
{
public:
B (int ba = 0, int bb = 0) : A(ba), b(bb)
{
cout << "call B ()" << endl;
}
private:
int b;
};
class C : public B
{
public:
C (int ca = 0, int cb = 0, int cc = 0)
: B(ca, cb), c(cc)
{
A (ca);
cout << "call C ()" << endl;
}
private:
int c;
};
int main ()
{
C tmp (1, 2, 3);
return 0;
}
#include <iostream>
using namespace std;
class A
{
public:
A (int aa = 0) : a(aa)
{
cout << "call A ()" << endl;
}
private:
int a;
};
class B : public A
{
public:
B (int ba = 0, int bb = 0) : A(ba), b(bb)
{
cout << "call B ()" << endl;
}
private:
int b;
};
class C : public B
{
public:
C (int ca = 0, int cb = 0, int cc = 0)
: A(ca), B(ca, cb), c(cc)
{
cout << "call C ()" << endl;
}
private:
int c;
};
int main ()
{
C tmp (1, 2, 3);
return 0;
}
#include <iostream>
using namespace std;
class A
{
public:
A (int aa = 0) : a(aa)
{
cout << "call A ()" << endl;
}
private:
int a;
};
class B : public A
{
public:
B (int ba = 0, int bb = 0) : b(bb)
{
A (ba);//这里显示调用基类的构造函数 会报错 程序2.cpp中却不会 不知为何?
cout << "call B ()" << endl;
}
private:
int b;
};
int main ()
{
B tmp (1, 2);
return 0;
}
编译之后报错:
g++ 1.cpp
1.cpp: In constructor `B::B(int, int)':
1.cpp:24: error: declaration of 'A ba' shadows a parameter
代码2.cpp,可以正常编译和执行
#include <iostream>
using namespace std;
class A
{
public:
A (int aa = 0) : a(aa)
{
cout << "call A ()" << endl;
}
private:
int a;
};
class B : public A
{
public:
B (int ba = 0, int bb = 0) : A(ba), b(bb)
{
cout << "call B ()" << endl;
}
private:
int b;
};
class C : public B
{
public:
C (int ca = 0, int cb = 0, int cc = 0)
: c(cc)
{
B (ca, cb);//这里也是显示调用基类的构造函数,为什么不会报错呢?
cout << "call C ()" << endl;
}
private:
int c;
};
int main ()
{
C tmp (1, 2, 3);
return 0;
}
运行结果如下:
g++ 2.cpp
./a.out
call A ()
call B ()
call A ()
call B ()
call C ()[/quote]
确实出现此问题,同时,我发现当类B在类C的初始化列表中初始化时,结果为
call A()
call B()
call C()
希望得到解释[/quote]
如果将类C的初始化列表写为
C (int ca = 0, int cb = 0, int cc = 0)
: B(ca, cb), c(cc)
{
……
}
这时候相当于给基类B的构造函数传递了值,出现
call A()
call B()
call C()
结果的原因是由于类C是从类B继承下来的,所以构造类C会先构造类B,即调用类B的构造函数。而类B又是从类A继承下来的,所以构造类B会先构造类A。所以是这个结果。function foo(const string& str) { /*..do something with str..*/ }
foo(string("wtf")); // 这里的 string("wtf") 与 B(ca, cb) 异曲同工
C (int ca = 0, int cb = 0, int cc = 0)
: c(cc)
{
B (ca, cb);
cout << "call C ()" << endl;
}
类C是类B派生出来的,在构造类C之前已经隐式调用了类B的构造函数了,我在类C的构造函数中又显示调用了类B的构造函数,这时为什么不算是重复构造呢?是不是只有隔代继承才有这种重复构造的说法呢?不知道我的理解对不对呢?
#include <iostream>
using namespace std;
class A
{
public:
A (int aa = 0) : a(aa)
{
cout << "call A ()" << endl;
}
private:
int a;
};
class B : public A
{
public:
B (int ba = 0, int bb = 0) : b(bb)
{
A (ba);//这里显示调用基类的构造函数 会报错 程序2.cpp中却不会 不知为何?
cout << "call B ()" << endl;
}
private:
int b;
};
int main ()
{
B tmp (1, 2);
return 0;
}
编译之后报错:
g++ 1.cpp
1.cpp: In constructor `B::B(int, int)':
1.cpp:24: error: declaration of 'A ba' shadows a parameter
代码2.cpp,可以正常编译和执行
#include <iostream>
using namespace std;
class A
{
public:
A (int aa = 0) : a(aa)
{
cout << "call A ()" << endl;
}
private:
int a;
};
class B : public A
{
public:
B (int ba = 0, int bb = 0) : A(ba), b(bb)
{
cout << "call B ()" << endl;
}
private:
int b;
};
class C : public B
{
public:
C (int ca = 0, int cb = 0, int cc = 0)
: c(cc)
{
B (ca, cb);//这里也是显示调用基类的构造函数,为什么不会报错呢?
cout << "call C ()" << endl;
}
private:
int c;
};
int main ()
{
C tmp (1, 2, 3);
return 0;
}
运行结果如下:
g++ 2.cpp
./a.out
call A ()
call B ()
call A ()
call B ()
call C ()[/quote]
确实出现此问题,同时,我发现当类B在类C的初始化列表中初始化时,结果为
call A()
call B()
call C()
希望得到解释A (ca);
表示声明一个A类型的变量 ca, 等价于
A ca;
但
A (ca + 0);
则表示用参数(ca+0)构造一个A类型的匿名对象。同理
B (ca, cb);
表示使用参数 ca, cb 构造一个匿名的B类对象。
这是由于编译器解析时语法优先级(我造的词)的原因造成的吧,看上去像是变更声明的换变量声明算,否则才考虑是不是是匿名变量构造(匿名变量用得少,所以优先级低吧)
无论如何,以上写法都不是调用基类或祖先类的构造函数的合法途径。首先要说,无论你写不写,基类的构造函数都会在任何一个本类声明的变量构造之前被调用,所以:
1. 基类的构造函数只能在初始化列表中调用
2. 无法隔代调用祖先类构造函数,因为这些函数已经被基类构造函数隐式调用过了,显示调用会引起重复构造,这是不允许的。
#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
protected:
A (int aa = 0) : a(aa)
{
cout << "call A ()" << endl;
}
private:
int a;
};
void func()
{
A(abc);
}
int _tmain(int argc, _TCHAR* argv[])
{
func();
return 0;
}
如果这么写就编译不过去了。
void func()
{
010314C0 push ebp
010314C1 mov ebp,esp
010314C3 sub esp,0CCh
010314C9 push ebx
010314CA push esi
010314CB push edi
010314CC lea edi,[ebp-0CCh]
010314D2 mov ecx,33h
010314D7 mov eax,0CCCCCCCCh
010314DC rep stos dword ptr es:[edi]
A(abc);
010314DE push 0
010314E0 lea ecx,[abc]
010314E3 call A::A (1031023h)
}
#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
public:
A (int aa = 0) : a(aa)
{
cout << "call A ()" << endl;
}
private:
int a;
};
void func()
{
A(abc);
}
int _tmain(int argc, _TCHAR* argv[])
{
func();
return 0;
}
func()的汇编是:
void func()
{
010314C0 push ebp
010314C1 mov ebp,esp
010314C3 sub esp,0CCh
010314C9 push ebx
010314CA push esi
010314CB push edi
010314CC lea edi,[ebp-0CCh]
010314D2 mov ecx,33h
010314D7 mov eax,0CCCCCCCCh
010314DC rep stos dword ptr es:[edi]
A(abc);
010314DE push 0
010314E0 lea ecx,[abc]
010314E3 call A::A (1031023h)
}
这个func函数实际上直接调用了class A的构造函数,参数是随机的(红色部分)。同样道理,你给的代码也是如此。
class C : public B
{
public:
C (int ca = 0, int cb = 0, int cc = 0)
: B(ca, cb), c(cc)
{
//A (ca); // 需要注释掉
cout << "call C ()" << endl;
}
private:
int c;
};
#include <iostream>
using namespace std;
class A
{
public:
A (int aa = 0) : a(aa)
{
cout << "call A ()" << endl;
}
private:
int a;
};
class B : public A
{
public:
B (int ba = 0, int bb = 0) : b(bb)
{
A (ba);//这里显示调用基类的构造函数 会报错 程序2.cpp中却不会 不知为何?
cout << "call B ()" << endl;
}
private:
int b;
};
int main ()
{
B tmp (1, 2);
return 0;
}
编译之后报错:
g++ 1.cpp
1.cpp: In constructor `B::B(int, int)':
1.cpp:24: error: declaration of 'A ba' shadows a parameter
代码2.cpp,可以正常编译和执行
#include <iostream>
using namespace std;
class A
{
public:
A (int aa = 0) : a(aa)
{
cout << "call A ()" << endl;
}
private:
int a;
};
class B : public A
{
public:
B (int ba = 0, int bb = 0) : A(ba), b(bb)
{
cout << "call B ()" << endl;
}
private:
int b;
};
class C : public B
{
public:
C (int ca = 0, int cb = 0, int cc = 0)
: c(cc)
{
B (ca, cb);//这里也是显示调用基类的构造函数,为什么不会报错呢?
cout << "call C ()" << endl;
}
private:
int c;
};
int main ()
{
C tmp (1, 2, 3);
return 0;
}
运行结果如下:
g++ 2.cpp
./a.out
call A ()
call B ()
call A ()
call B ()
call C ()