免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: dream-girl
打印 上一主题 下一主题

[函数] 构造函数? [复制链接]

论坛徽章:
0
51 [报告]
发表于 2004-12-27 20:42 |只看该作者

构造函数?

[quote]原帖由 "gvim"]kj501当我看到那段E文的时候,理解和你一样。呵呵,后来才发现那个V其实是特指的代码段里面的那个V而不是泛指的“类”[/quote 发表:

呵呵,深有同感! 我估计可能还有不少人要掉到这个陷阱里。

论坛徽章:
0
52 [报告]
发表于 2004-12-27 20:43 |只看该作者

构造函数?

class A
{
A(){cout<<"A"<<endl;}
}

class b
{
public:
   A a;
  b(){cout<<"b"<<endl;}
}

论坛徽章:
0
53 [报告]
发表于 2004-12-27 20:46 |只看该作者

构造函数?

If a member class object is not present in the member initialization list but has an associated default constructor, that default constructor must be invoked.

Prior to that, if there is a virtual table pointer (or pointers) contained within the class object, it (they) must be initialized with the address of the appropriate virtual table(s). j

这两句你看看那实现初始化vptr还是先调用constructor?

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
54 [报告]
发表于 2004-12-27 21:11 |只看该作者

构造函数?

我的原话是这样的:
编译器合成的构造函数,1 负责调用基类的缺省构造函数(如果基类有缺省构造函数的话),2 负责正确初始化虚函数表的指针,并添加进类的相应域中。

我并没有告诉你“那实现初始化vptr还是先调用constructor”,如果你真的不理解,好吧。

假设有这样的关系。

  1. class C
  2. {
  3.     virtual void fc() =0;
  4.     C()
  5.     {
  6.     }
  7. };

  8. class B:public C
  9. {
  10.     B(){}
  11. };

  12. class A:public B
  13. {
  14. };

  15. 这里A没有提供缺省构造函数,所以编译器提供。并且扩展A的构造函数为:
  16. A::A()
  17. {
  18.     vptr=...//设定虚函数表
  19.    C();
  20.      B();
  21. }
复制代码

vptr是编译器合成出来的构造函数A()负责初始化的,C()和B()是编译器合成出来的构造函数A()负责调用的。
还不理解,请看书。

论坛徽章:
0
55 [报告]
发表于 2004-12-27 21:27 |只看该作者

构造函数?

这里A没有提供缺省构造函数,所以编译器提供。并且扩展A的构造函数为:
A::A()
{
    vptr=...//设定虚函数表
   C();
     B();
}

这是你自己想的,实际上不是这样的,而且你想的这个也是不可行的.
首先你合成出来的这个是错误的,其次vptr也不是在这里初始化的,这种显示的调用构造函数是不好的

  1. #include <iostream>;

  2. using namespace std;
  3. class A
  4. {
  5. public:
  6.     int i;
  7.     A():i(10){cout<<i<<endl;size();}
  8.     virtual void size(){cout<<sizeof(A)<<endl;}   
  9. };

  10. class B :public A
  11. {
  12.     public:
  13.         int j;
  14.         //B():j(20){A();cout<<i<<","<<j<<endl;size();}//显式的调用构造函数不是系统会构造出来的.
  15.         B():A(),j(20){cout<<i<<","<<j<<endl;size();}//符合初始化的程序
  16.         virtual void size(){cout<<sizeof(B)<<endl;}
  17. };
  18. int main()
  19. {
  20.     B b;
  21.     system("pause");
  22. }
复制代码


你可以去掉注释,把下面那个构造函数注释,看看结果.

论坛徽章:
0
56 [报告]
发表于 2004-12-27 21:32 |只看该作者

构造函数?

所以我说
编译器合成的构造函数既不负责调用基类的缺省构造函数(如果基类有缺省构造函数的话),也不负责正确初始化虚函数表的指针,并添加进类的相应域中。
我说的先后顺序也是为了说明这一点.

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
57 [报告]
发表于 2004-12-27 21:42 |只看该作者

构造函数?

晕,你太有创意了,怎么能这样理解啊。
首先,我的那些是伪代码,不是真正执行的代码。其次我在A类里面没有提供A(),那个A()是编译器合成出来的,那种调用手法是编译器将C++转换为C以后的内部调用手法,也不是人可以干预的。

我再最后强调一次,就算你提供了构造函数,并不是编译器就一定按照你的显示构造函数调用,它按照它自己的需要(不是程序员的需要)往里面添加代码,完成必要的初始化动作。另一方面,你没有提供构造函数的时候,编译器按照它的需要为你合成构造函数(也可能不需要),然后再完成它需要的初始化动作。

论坛徽章:
0
58 [报告]
发表于 2004-12-27 21:50 |只看该作者

构造函数?

原帖由 "gvim" 发表:
晕,你太有创意了,怎么能这样理解啊。
首先,我的那些是伪代码,不是真正执行的代码。其次我在A类里面没有提供A(),那个A()是编译器合成出来的,那种调用手法是编译器将C++转换为C以后的内部调用手法,也不是人可?.........


我同意你后面的那一句,前面哪句好像是c++很久以前的事情?

论坛徽章:
0
59 [报告]
发表于 2004-12-27 21:53 |只看该作者

构造函数?

原帖由 "converse" 发表:


是呀,think一书就是这样写的呀:
If any constructors are defined, however, and there’s no default constructor, the instances of V above will generate compile-time errors.
(粗译如下)如果没有定?.........


FT,我自己翻译错了,应该是如果定义了构造函数而没有定义缺省构造函数的话就会出错。

论坛徽章:
0
60 [报告]
发表于 2004-12-27 21:53 |只看该作者

构造函数?

不过我还是坚持vptr初始化先于构造函数的调用.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP