一个C++类一般至少有四大函数,即构造函数、拷贝构造函数、析构函数和赋值函数,一般系统都会默认。但是往往系统默认的并不是我们所期望的,为此我们就有必要自己创造他们。在创造之前必须了解他们的作用和意义,做到有的放矢才能写出有效的函数。
构造函数就是为类申明的对象初始化。比如 String str;它就是为String类申明一个对象str并把它初始化,具体把str初始化成什么,这当然就是函数体怎么写的问题了。
eg:
class String
{
private:
char* content;
int len;
int size;
public:
String()
{
content = new char[1];
content[0] = '/0';
len = 0;
size = 1;
}
它则就把str初始化为一个空的字符串。就像我们常见的int i;就是给int类申明一个对象i,而具体把i初始化成谁了那就的问int的作者了。您是String类的作者它的初始化当然你规定了。举一反三,你就会写出这样的语句:String str = “abcdeg”;//相当于 int i = 0,和char类型不同;这样的情况我们就会发现不能运行了。当然,就是构造函数的问题了。我们知道 int i=0相当于int i(0) 同理 String str=”abcdeg”也就相当于String str(“abcdeg”)了,所以就必须写一个带参的构造函数
String(char* str)
{
len = strlen(str);
size = len + 1;
content = new char[size];
strcpy(content, str);
}
那么,String str(“abcdeg”)就申请成功了。同样我可以再写一个限定大小的字符串。
String(int newsize)
{
size = newsize;
len = 0;
content = new char[size];
}
再往下推,我们知道 int i=0;int j=i;那么能不能用String str=”jaksdhj”; String str1=str;这就引出了拷贝构造函数的概念,即用一个对象去初始化一个对象,可以看作String str1(str)。
String(const String & newstr)
{
this->size = newstr.size;
this->content = new char[this->size];
this->len = newstr.len;
strcpy(this->content, newstr.content);
}
注意:这里用了引用传参。
把对象的初始化工作放在构造函数中,把清除工作放在析构函数中。当对象被创建时,构造函数被自动执行。当对象消亡时,析构函数被自动执行,把一切内存垃圾清理,可见他的重要。如果没有析构函数或析构函数不正确就会发生内存泄露等问题,后果非常危险。这是一个String的析构函数:
~String()
{
delete[] content;
}
从中我们看见了new和delete的匹配,这下就不用担心忘了对象的初始化和清除工作。一个类最基础的东西就基本上完成了,只剩一个赋值函数,很多刚学习C++的人搞不清赋值函数到底用什么用和是干什么的。其实说白了赋值函数就是一个赋值“=”,它既是为了实现一个对象对另一个对象赋值,也就是为了让“str = str1;”这句话运行成功。一般系统也会面默认一个赋值函数,但大多数情况他并不能给出我们想要的结果,所以我就很有必要自己来写赋值函数。相当于重载了一次‘=’运算。
String& operator = (const String& other)
{
if(this == &other)
{
return *this;
}
this->size = other.size;
this->content = new char[this->size];
this->len = other.len;
strcpy(this->content, other.content);
return *this;
}
这样就完成了四大函数(实质是三种)的重写,这个类对你就完全自主了。每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数)。构造函数和赋值函数有着很大的区别,构造函数是在对象创建时调用的,而赋值函数使对象已经创建好了存在之后再赋值时调用的。至于什么时候写怎么样的构造函数我认为根据你的需要,尽量多写几种,那样的话用起来就比较灵活。有时候我们懒得写赋值函数和拷贝构造函数,,又不允许别人使用编译器生成的缺省函数,那么我们可以只需将拷贝构造函数和赋值函数声明为私有函数,不用编写代码。如:
class String
{ …
private:
String (const String &a); // 私有的拷贝构造函数
String & operate =(const String &a); // 私有的赋值函数
};