Loaden,akirya,taodm,jackyjkchen,mstlq,do_fork、whg01进

高性能架构探索 2009-12-11 02:54:03
你们几个跟还有那些有星的,在csdn c++里,对我来说神一样的人物,或许我所提的问题,你们是不屑回答,但我真的希望能够得到各位权威的回答,对于你们除了崇拜,剩下的就只有膜拜了,我注册不久,发帖不多,但真的希望能得到各位的回答,
级别不够,一次只能给100分,见谅;

1、我想知道合成是什么概念,刚才在网上找了下,对合成的定义如下:当一个类的成员变量的类型是另一个类时,称之为“合成(composite)”。不知道各位高手是否认同
2、class A
{
public:
int i;
int j;
vrtual void f();
};
书上写的不会合成默认构造函数和析构函数,因为其没有成员对象
而如果
class B
{
public:
int i;
A a;
};
这样也不会合成一个默认构造函数和析构函数,因为a没有构造函数和析构函数 :出自《深度探索c++对象模型》
3、之前我对合成的概念自定义如下:
class A
{
public:
int i;
int j;
vrtual void f();
};
A a;//编译器会自动生成一个默认构造函数和析构函数,而以为合成概念就相当于生成
4、对于上述类定义,编译器会不会构造一个默认的析构函数??
如果我不需要任何A 对象,比如没有 A a等,那么编译器还不会不自动生成一个默认构造函数和析构函数
5、
如果一个类没有定义构造函数,那么编译器会生成一个默认的构造函数,那么如果一个类没定义析构函数,还会不会生成默认的析构函数
6、是不是每个类都会有一个析构函数,如果我们没定义,系统会自动生成一个默认析构函数,如果是,析构函数的作用是什么?
7、默认析构函数与默认构造函数的问题类似。即,只有在编译期需要的时候生成,目地是完成清理的工作,与空间回收无关。而且,析构函数并不一定要于构造函数配对。比如类中只是有一个虚函数的时候,就不必生成默认析构函数。所有的析构和构造对称出现的想法,都只是我们出于美学的主观臆断罢了。而对析构函数的扩展,其顺序与构造函数相反,这一点倒是符合了对称性。
上面这句话对否??为什么?

...全文
418 53 打赏 收藏 转发到动态 举报
写回复
用AI写文章
53 条回复
切换为时间正序
请发表友善的回复…
发表回复
IanFang 2009-12-14
  • 打赏
  • 举报
回复
[Quote=引用 51 楼 csdmadmimistrator 的回复:]
引用 50 楼 ianfang 的回复:
就算是站在编译器实现者角度来讲,有谁规定POD类型编译器就不能生成一个构造函数?生成一个逐位拷贝的拷贝构造函数不行?生成一个无用的缺省构造函数不行?内联使之失去了痕迹就是没有过?那很多编译器还产生多个析构函数实体呢,《深度探索C++对象模型》怎么没讲啊?不要动不动就摆四条。


楼上的你将默认构造函数和拷贝构造函数混淆起来了....
站在实现者的角度来说,你当然可以给任何类生成一个默认构造函数(就算它是无用的)
但是你却无法自己决定不给某个类生成默认构造函数(如果你的类没有定义任何构造函数的话)
正如前面我所说的,在某种情况下必须要生成一个默认构造函数
而这才是我们讨论的重点
[/Quote]

是我混淆了还是你不理解中文?
失落的凡凡 2009-12-13
  • 打赏
  • 举报
回复
我没星星 楼主表BS我

我猜楼主的困惑在于“合成”这个慨念到底是指什么,你写的第1条和后面提到的“合成”不是同一个慨念。其中第一条里的合成是很少提到,因为很普通。

而“合成默认构造函数”,是指你没有显式给类定义一个构造函数的时候,编译器会自动给类添加一个默认构造函数。

另外再说一下默认构造函数,免得你忽略这个慨念。默认构造函数就是无参数的构造函数。
CSDMAdmimistrator 2009-12-13
  • 打赏
  • 举报
回复
[Quote=引用 50 楼 ianfang 的回复:]
就算是站在编译器实现者角度来讲,有谁规定POD类型编译器就不能生成一个构造函数?生成一个逐位拷贝的拷贝构造函数不行?生成一个无用的缺省构造函数不行?内联使之失去了痕迹就是没有过?那很多编译器还产生多个析构函数实体呢,《深度探索C++对象模型》怎么没讲啊?不要动不动就摆四条。
[/Quote]

楼上的你将默认构造函数和拷贝构造函数混淆起来了....
站在实现者的角度来说,你当然可以给任何类生成一个默认构造函数(就算它是无用的)
但是你却无法自己决定不给某个类生成默认构造函数(如果你的类没有定义任何构造函数的话)
正如前面我所说的,在某种情况下必须要生成一个默认构造函数
而这才是我们讨论的重点
IanFang 2009-12-12
  • 打赏
  • 举报
回复
C++标准里已经说得很明白了。不要老搬《深度探索C++对象模型》来说事。
在语言使用者的层面,你需要知道些什么,该怎么认为。
在语言实现者角度,又该做些什么。
那么你现在是站在什么角度?

就算是站在编译器实现者角度来讲,有谁规定POD类型编译器就不能生成一个构造函数?生成一个逐位拷贝的拷贝构造函数不行?生成一个无用的缺省构造函数不行?内联使之失去了痕迹就是没有过?那很多编译器还产生多个析构函数实体呢,《深度探索C++对象模型》怎么没讲啊?不要动不动就摆四条。

老观点,
语言标准里面怎么说就怎么认为,因为你是语言的使用者,你必须跟着标准走。
如果你现在是站在实现者的角度,问题就没有定论,C++标准对多态的实现机制尚且持放任的态度,更何况那“四条准则”了,没有谁规定编译器非得只有在这四种情况下才能产生必要的函数,只能说它稍微普遍一点。编译器也是程序,也是人写的,它不能天马行空,也得符合开发者自己定的框架和思路。但是毫无疑问,最后的结果是他们的编译器表现出来的行为符合C++标准。
jeff_nie 2009-12-11
  • 打赏
  • 举报
回复
进来看牛人的
healer_kx 2009-12-11
  • 打赏
  • 举报
回复
给这个帖子起个名字吧,星星点灯~~~
太乙 2009-12-11
  • 打赏
  • 举报
回复


1、我想知道合成是什么概念,刚才在网上找了下,对合成的定义如下:当一个类的成员变量的类型是另一个类时,称之为“合成(composite)”。不知道各位高手是否认同
============================================
这个东西比较微妙,和组合、合成、聚合之类的很容易混淆,可以建议lz看看设计模式!我不太认同这个观点,不能这么简单的说
参考url:http://www.jdon.com/designpatterns/composite.htm
============================================
2、class A
{
public:
int i;
int j;
vrtual void f();
};
书上写的不会合成默认构造函数和析构函数,因为其没有成员对象
而如果
class B
{
public:
int i;
A a;
};
这样也不会合成一个默认构造函数和析构函数,因为a没有构造函数和析构函数 :出自《深度探索c++对象模型》
============================================
默认构造函数只有在以下之列才会被合成:
1) 当class内含一个member object 而后者的class声明有一个constructor时(不论是被class设计者明确地声明,或者是被编译器合成)。
2) 当class继承自一个base class而后者存在有一个constructor时(不论是被明确声明还是被合成所得)。
3) 当class声明了一个或多个virtual function时(需要对vptr初始化)
4) 当class派生自一个继承串链,其中有一个或多个virtual base classes时。
============================================
3、之前我对合成的概念自定义如下:
class A
{
public:
int i;
int j;
vrtual void f();
};
A a;//编译器会自动生成一个默认构造函数和析构函数,而以为合成概念就相当于生成
===========================================
参考第一个问题和第二个问题
===========================================
4、对于上述类定义,编译器会不会构造一个默认的析构函数??
如果我不需要任何A 对象,比如没有 A a等,那么编译器还不会不自动生成一个默认构造函数和析构函数
==========================================
会!
==========================================
5、
如果一个类没有定义构造函数,那么编译器会生成一个默认的构造函数,那么如果一个类没定义析构函数,还会不会生成默认的析构函数
==========================================
参考第2个问题,析构和构造是对应的,
==========================================

6、是不是每个类都会有一个析构函数,如果我们没定义,系统会自动生成一个默认析构函数,如果是,析构函数的作用是什么?
==========================================
不一定,如果需要而你又没定义,系统会自动生成一个
析构函数的作用比较多:(对应上面)
调用member obj的析构函数
调用基类的析构函数
重置vptr指针
调用虚基类的析构函数
==========================================

7、默认析构函数与默认构造函数的问题类似。即,只有在编译期需要的时候生成,目地是完成清理的工作,与空间回收无关。而且,析构函数并不一定要于构造函数配对。比如类中只是有一个虚函数的时候,就不必生成默认析构函数。所有的析构和构造对称出现的想法,都只是我们出于美学的主观臆断罢了。而对析构函数的扩展,其顺序与构造函数相反,这一点倒是符合了对称性。
上面这句话对否??为什么?
===============================
基本上正确。
参考我上面的回答






yshuise 2009-12-11
  • 打赏
  • 举报
回复


如果没有构造函数,谁来负责调用子类的默认构造函数或者数据成员的默认构造函

你太会搞笑了。我还把“一块木板”同 “太阳”联系起了。
但是这不是重点。
因为RAII的重点是管理资源的问题。你不用重点来表达,却用一个相对次要的来表达,只能说明了你的纰漏。
太乙 2009-12-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 jackyjkchen 的回复:]
你好像搞复杂了……构造函数和析构函数都是类的必需部分,没有明确定义的话都会生成一个默认的……只要没有就生成

深度探索c++对象模型 这本书不适合现在看,这本书没有什么实用性,是有了一定开发经验后能够让以前疑问得到解答,没有开发经验,看这本书只会有更多的疑问……


[/Quote]



1楼的有问题吧???c++的标准说,必须要有必要的时候才生成啊!!

比如:
对于
class A{private : int i;int j;};

这样的类是不会生成默认构造函数的!!

别误导lz啊~~~
baihacker 2009-12-11
  • 打赏
  • 举报
回复
默认构造函数是指调用时不需要实参的构造函数.
默认构造函数可能是用户定义的,也有可能是在用户没有定义的时候,编译器偷偷干的.
如果用户没有定义析构函数,也会偷偷搞个析构函数.

有时,这些函数是平凡的,不做任何事.但是也有时,在里面需要做点小动作,这取决于具体环境.

在平凡的时候,就是不做什么.
其实意义在于保证了某种完整性.

在平凡的时候,可能在最终生成的代码中看不到这些函数的调用(甚至连这个函数都没有).但并不等于说,就不存在了,因为这只是在最终实现中的不存在.

想起来一句话:
存在而不存在:透明
不存在而存在:虚拟
CSDMAdmimistrator 2009-12-11
  • 打赏
  • 举报
回复
同时回复41楼:
你所说的,只是知其然,而不知其所以然

你看这书的时候,是只是记住什么时候编译器需要合成一个默认构造函数或者析构函数么?
有没有认真地思考过编译器为什么要这样做?
如果你考虑过这一问题,你压根就不需要记住....任何东西
CSDMAdmimistrator 2009-12-11
  • 打赏
  • 举报
回复
回复41楼
2.RAII:自动调用构造函数.... //如果没有构造函数,谁来负责调用子类的默认构造函数或者数据成员的默认构造函
自己想想吧,我那说法跟你补充的那两点在本质上是否有什么实质的区别

已经三年多没有看那本书了
那里面的东西需要背的么?
站在编译器实现者的角度去考虑问题吧
你就会发觉一切都会变得那么的清晰


yshuise 2009-12-11
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 csdmadmimistrator 的回复:]
引用 21 楼 yshuise 的回复:
呵呵,c的struct就从来没有什么构造函数和析构函数。


也就是说,以下代码跟A是C-Struct的时候生成的代码是一样的,那就是不需要默认构造函数了
如果跟A是C-Struct的时候生成的代码不一样,那就需要编译器来合成一个默认构造函数了(当然,前提是,你没有定义任何构造函数)
C/C++ codeA a;

然后自己分析一下
在本质上,class 比C-struct多引入了什么新特性,那些新特性是必须要编译器必须要额外的工作才能让class正常工作的?
1.多态:引入了虚表          //如果没有构造函数,谁来负责初始化虚表?
2.RAII:自动调用构造函数.... //如果没有构造函数,谁来负责调用子类的默认构造函数或者数据成员的默认构造函数?
3.虚拟继承:     //你觉得虚拟继承是如何实现的?如果没有构造函数,如何实现虚拟继承?
想清楚了这些问题,你就自动,啥时候编译器会偷偷地给你合成一个默认构造函数了
同理,析构函数也一样

[/Quote]
我看了下书,你的1,3点算对。
但是你还缺了两点,你的第二点用RAII来形容是不对的。
其他的两点:
第一:“带有Default Constructor”的 Member Class Object
第二:“带有Default Constructor”的 Base Class
CSDMAdmimistrator 2009-12-11
  • 打赏
  • 举报
回复
39楼是回复32楼的
CSDMAdmimistrator 2009-12-11
  • 打赏
  • 举报
回复
看25楼
如果自己还不知道什么时候编译器会偷偷地给你生成一个默认构造函数或者析构函数的话,那认真分析以下以下代码,规则很简单


[Quote=规则:]
以下情况下必定要有构造函数和析构函数(要么是用户定义的,要么是编译器帮你生成的)
1.如果这个类有虚表,那么必定要有构造函数和析构函数,以调整vptr
2.如果这个类的继承体系中有虚拟继承,必定要有构造函数,至于有没有析构函数

以下情况可能只有默认构造函数或者析构函数,或者两者皆有(要么是用户定义的,要么是编译器帮你生成的)
1.如果一个类的数据成员或者基类有默认构造函数(无论是自己定义的,还是编译器生成的),那么它必定要有一个构造函数(要么是用户定义的,要么是编译器帮你生成的),用以调用数据成员或者基类的默认构造函数,当然还有可能做其它事情,如调整vptr

2.如果一个类的数据成员或者基类有析构函数(无论是自己定义的,还是编译器生成的),那么它必定要有一个构造函数(要么是用户定义的,要么是编译器帮你生成的),用以调用数据成员或者基类的析构函数,当然还有可能做其它事情,如调整vptr
[/Quote]
taodm 2009-12-11
  • 打赏
  • 举报
回复
哎,楼主啊,标准的原文已经贴在那里了,就劳您稍微看看吧。
taodm 2009-12-11
  • 打赏
  • 举报
回复
由于《深度探索。。》是侯捷翻译的,用了很多台湾风格的词汇。
所以,如果你对某些名词有好奇,应该找来英文电子版看看原文所用词汇
这样很多疑问自解。
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 pengzhixi 的回复:]
引用 33 楼 namelij 的回复:
啊!!?合成到底指的是什么意思?现在还不是很明白

你可以理解为编译器帮你提供
[/Quote]
合成有没有限制:比如说 一个类对象 必须是该类的 数据成员或者参量,我是在网上搜索的,参见我的问题1
pengzhixi 2009-12-11
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 namelij 的回复:]
啊!!?合成到底指的是什么意思?现在还不是很明白
[/Quote]
你可以理解为编译器帮你提供
yshuise 2009-12-11
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 namelij 的回复:]
啊!!?合成到底指的是什么意思?现在还不是很明白
[/Quote]
意思就是你没有写构造函数,编译器帮你生成一个。
加载更多回复(33)

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧