如果我们定义的类没有定义任何构造函数。那么我们用类名声明一个对象,还是可以正确的编译和运行,那是因为类通过一个特殊的构造函数来控制默认初始化过程,这个函数叫做默认构造函数。默认构造函数无任何实参。合成的默认函数只适合一些简单的类。
构造函数的几种说明
1.构造函数没有返回值,他的作用只是初始化对象,因此也不需要在定义构造函数的时候声明类型,这是他和一般函数一个重要的不同之点。
2.构造函数不需要用户调用,也不能被调用。
{
对象.构造函数 这是错的!!!
}
3.可以用一个类对象初始化另一个对象。
Time t1;
Time t2 =t1;
——————
比较特殊的构造方法:
Box::Box (int h,int w,int len):height(h),width(w),length(len){ }
一个冒号 没有分号;
拷贝函数
拷贝函数 分为深拷贝和浅拷贝;
浅拷贝包括值的拷贝,而深拷贝多了对内存分配的拷贝(对有动态分配的类使用)
下面是一道课堂练习题
*上周讲过,对象赋值时,(1) 对象的赋值只对其中的数据成员赋值,而不对成员函数赋值;(2) 类的数据成员中不能包括动态分配的数据,否则在赋值时可能出现严重后果。
例如:
class String
{public:
String(const char* p);
private:
int len;
char* Str;
};
String∷String(const char* p);
{
len = strlen(p);
Str = new char[len+1];
strcpy(Str,p);
}
问:会产生什么严重后果?此外,为了消除后果,如果主函数中希望使用对象的复制,请进一步完善程序。*
答案:
#include<iostream>
#include<string.h>
using namespace std;
class String
{
private:
int len;
char* Str;
public:
void showStr()
{
cout<<"string:"<<Str<<",length:"<<len<<endl;
}
String()
{
len=0;
Str=NULL;
}
String(const char *p)
{
len=strlen(p);
Str=new char [len+1];
strcpy(Str,p);
}
String(String &r)
{
len=r.len;
if(len!=0)
{
Str=new char[len+1]; //重新申请一个空间
strcpy(Str,r.Str);
}
}
~String()
{
if(Str!=NULL)
{
delete[]Str;
Str=NULL;
}
}
}
如果对有动态分配的类浅拷贝的话,个对象的析构函数将对同一个内存空间释放两次,这就是错误出现的原因。
拷贝构造函数其时就是一个特殊的构造函数,操作的还是自己类的成员变量,所以不受private的限制。