类的隐式成员函数

C++自动提供了下面这些成员函数

默认构造函数,如果没有定义构造函数

复制构造函数,如果没有定义

赋值操作符,如果没有定义

默认析构函数,如果没有定义

地址操作符,如果没有定义


默认构造函数

 编译器将提供一个不接受任何参数,也不执行任何操作的构造函数,这是因为创建对象时总是会调用构造函数。默认构造函数使得类在初始化时的值时未知的。

 如果希望在创建对象时显式的对它进行初始化,或需要创建对象数组时,则必须显式的定义默认构造函数。这种构造函数没有任何参数,但是可以使用它来设定特定的值:

Klunk::Klunk()
{
	klunk_ct=0;
	...
}
 带参数的构造函数也可以是默认构造函数,只要所有的参数值都有默认值

Klunt(int n=0){klunt_ct=n;}
 **但只能由一个默认构造函数


复制构造函数

复制构造函数用于将一个对象复制到新创建的对象中。也就是说,它用于初始化过程中,而不是常规的赋值过程中。

class_name(const class_name &)
新建一个对象并将其初始化为同类现有对象时,复制构造函数都将被调用。每当程序生成了对象的副本时,编译器都将使用复制构造函数。具体的说,当函数按值传递对象或函数返回对象时,都将使用复制构造函数。

复制构造函数的功能:默认的复制构造函数逐个复制非静态成员,复制的是成员的值。 如果成员本身就是类对象,则将使用这个类的复制构造函数来复制成员对象。

使用显式复制构造函数来解决问题:复制构造函数应当复制字符串并将副本的地址付给str成员,而不是复制字符串的地址。这样每个对象都有自己的字符串,而不是引用另一个对象的字符串。调用析构函数时都将释放不同的字符串,而不会试图去释放已经被释放的字符串。

赋值操作符:c++通过重载赋值操作符实现类对象复制

Class_name & Class_name::operator =(const Class_name &)
与复制构造函数相似,赋值操作符的隐式实现也可以对成员逐个复制。如果成员本身就是类对象,则程序将使用为这个类定义的赋值操作符来复制该成员,但静态数据不受影响。

解决赋值的问题:由于目标对象可能引用了以前分配的数据,所以函数应使用delete[]来释放这些数据。 函数应该避免将对象赋值给自身;否则,给对象重新赋值之前,释放内存操作可能删除对象的内容。函数返回一个指向调用对象的引用。

应定义一个赋值构造函数,深度赋值另一个对象初始化为另一个对象,通常这种构造函数与下面类似:

String::String(const String &st)
{
	num_string++;
	len=st.len;
	str=new char[len+1];
	std::strcpy(str,st.str);
}
具体的说,赋值构造函数应该分配足够的空间信息存储赋值的数据,并赋值数据,而不仅仅是数据的地址。

应当定义一个赋值操作,通过深度赋值将一个对象赋值给另一个对象:

String &  String:: operator=(const String & st)
{
	if(this==&st)
		return *this;
	delete [] str;
	len=st.len;
	str=new char[len+1];
	std::strcpy(str,st.str);
	return *this;
}
下面包含了两个不正确的范例以及一个良好的构造函数的范例:

String::String()
{
	str="default string";
	len=std::strlen(str);
}
String::String(const char *s)
{
	len=std::strlen(s);
	str=new char;
	std::strcpy(str,s);
}
String::String(const String &st)
{
	len=st.len;
	str=new char[len+1];
	std::strcpy(str,st.str);
}
第一个构造函数没有使用new来初始化str。对默认对象调用析构函数时,析构函数使用delete来释放str。对不是使用new初始化的指针使用delete时,结果将是不确定的。

第二个构造函数中使用了new,但分配的内存数量不正确,因此,new返回的内存块只能保存一个字符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值