- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
类的构造函数
类的构造函数
一 构造函数。
讲述以前,我们来看一个类声明的例子:
class String
{
public:
//String();
String(const char *str = NULL); // 普通构造函数
String(const String other); // 拷贝构造函数
~ String(void); // 析构函数
String operate =(const String other); // 赋值函数
private:
char* m_data; // 用于保存字符串
int m_iLength;
}
这个类中有两个成员变量,我以前讲过在声明一个变量尤其是指针变量,最好在声明的时候就将其进行初始化,如在函数中
int GetAverage()
{
int iLength = 0;
char* pchArray = NULL;
}
这样做的目的是防止对变量进行非法操作,但是在类的声明中我们不能对其进行直接初始化,那我们应该在哪里初始化这些成员变量了,答案是在类的构造函数中进行。所以我们说构造函数的功能是:
1 功能: 定义一个类的新实例时,完成类实例的初始化,确保对象被正确的建立。
那什么样的函数是构造函数,他有哪些特点呢?
2 特点:
① 构造函数必须与class名称相同
② 构造函数不应指定返回值类型,亦不需要返回值
③ 不支持虚机制,通常构造函数本身也不声明为虚函数
④ 构造函数可以被重载。
我们特别来解释一下第三个特点, 构造函数中不支持虚机制,即在构造函数的函数体中调用一个虚函数的情况,被调用的只是这个函数的本地版本。也就是说,虚机制在构造函数中不工作。我觉得一般的同学只要知道这个特点就足够了,如果有兴趣的同学可以参考《C++编程思想》P292页,其中有较为详细的说明。
构造函数可以重载,所以构造函数有多种类型,常见的几种重载形式有:
3 常见的构造函数重载形式
3.1 缺省构造函数: 他有两种情况
a 不接受任何参数,即参数表是空的
b 它为每个参数提供了默认值
注意:在类的声明中只能出现其中的一种形式。
如String类声明的那样,但是我们必须注意这两种形式往往不能同时出现,为什么呢?主要是这样将引起二义性,当我们这样定义一个String类时
String str;
系统就不知道链接哪一个构造函数了,因为他可以调用无参数的构造函数但是同时系统也可以认为我们没有提供额外的参数,而按缺省的参数调用函数String(const char *str = NULL);所以二义性就产生了。我们因该去掉一个声明。
3.2 拷贝构造函数: 拷贝函数是一个非常重要的构造函数形式,而且使用和理解都比较麻烦,所以我们将花比较大的篇幅来介绍。
a 函数原型: X(X) 也就是函数名与类名同名,他有唯一的一个参数是该类的一个引用
事实上我们在使用过程当中常常在参数声明前面添加const修饰符号,象String声明的那样,为什么要加上const修饰符呢?因为该参数是一个输入参数,是不应该在函数体中被改变的所以我们在参数声明时就加上这个限制,以防误操作而将其值改变了。
但是又有同学会说,我以前从来没有自己定义拷贝构造函数,系统也照样能正常工作,那是因为系统我们提供了一个缺省拷贝构造函数。
b 缺省拷贝构造函数:按位拷贝
当我们将String中的拷贝构造函数屏蔽调,而不提供自己的拷贝构造函数时 系统会为我们提供一个缺省构造函数,它完成一个按位拷贝的功能。这样当我们按如下方式定义两个变量时:
String a;
String b(a);这时系统就会为我们将a中的各个成员变量按位拷贝到b中的成员变量中,使b中的成员变量具有与a完全一样的内容。这种按位拷贝的功能大多数情况是能够正确工作的,但是有些情况我们必须定义自己的拷贝构造函数,否则将产生很大的纰漏。
c 自己定义拷贝函数的必要性:
当对象中含有成员指针时,如上述的String类。象下面定义两个String对象:
String str1;
String str2(str1);
由于是按位拷贝,这时str1.m_data和str2.m_data具有一样的内容,意思就是说str1.m_data和str2.m_data指向同一个内存,这样当str1无效后,将释放str1.m_data所指向的内存,而
str2还有效,他将继续操作数据成员str2.m_data,而它所指向的内存已经不存在,这意味着str2正对一个不存在的内存进行操作,产生的后果难以预料,所以在类内有指针成员变量时,我们往往应该提供自己的拷贝构造函数。
4 构造函数的调用顺序 (由于时间的关系我们下次课在讲)。
当类之间有了继承,组合关系后,构造函数将按怎样的顺序调用
文档评论(0)