构造类的大三原则(读自VCKBase),及拷贝构造函数与=运算符的重载

来源:互联网 发布:护肤品数据 编辑:程序博客网 时间:2024/06/07 14:18

曾在VCKBase上读到构造类的大三原则,当时没有在意,现在将其摘在这里

著名的"大三规则"或"大二规则"如是说:如果一个类需要任何下列的三个成员函数之一,便三者全部要实现,
这三个成员函数是:拷贝构造,赋值操作符,析构函数.
一般来说,这个规则指的是从自由存储区分配内存的类.
其实,很多类只要遵循"大二规则"即可,也就是说只要实现拷贝构造,赋值操作符就可以了,析构函数并不总是必需的.
看下面的这个类:

class Year
{
private:
  int y;
  bool cached; // 该类的对象实例可被缓冲或隐藏吗?
public:
  //...
  Year(int y);
  Year(const Year& other) // 被缓冲或隐藏的对象不能实现拷贝
  {
    y = other.getYear();
  }  
  Year& operator =(const Year&other) //被缓冲或隐藏的对象不能实现拷贝
  {
    y = other.getYear();
    return *this;
  } 
  int getYear() const { return y; }
};//注意: 这个类(Year)不需要析构函数

在这个例子中,类 Year 在构造期间并不从自由存储区分配内存,也不需要获取其它的任何资源.
但是,这个类需要一个用户定义的拷贝构造函数和赋值操作,以便保证成员"cached"的值不会被拷贝,
因为每一个单独的对象都会被分开处理.

好上面是人家说的,加我自己的体会,根据C++教材上的说明一般的类的默认拷贝构造函数就够用了,但如果类中有指针类变量就要小心了,我自己就在这上面出过问题,所以一定要谨记

我在自己实现一个类似于CString的类时,前面实现一个基本的构造函数,然后就实现一个=的重载,格式如下
const CMyCString &operator =(const CMyCString Src);
注意参数不是用的引用,在代码中实现中就出现了内存错误
 CMyCString MyString("hello the world");
 CMyCString str3;
 str3 = MyString;
查找原因如下
1.重载=时参数用的不是引用,这样参数中用到了默认的拷贝构造函数,而类中有指针,这样拷贝构造函数不能实现此功能
解决方法可以用
1.重载=时参数用引用(最好)
2.重载=时参数不引用,实现一个正确的拷贝构造函数

1.拷贝构造函数在传递参数时使用(引用参数不使用)
void Func(CTest theTest) //调用了拷贝构造函数
2.当函数中的局部对象被被返回给函数调者时,也将建立此局部对象的一个临时拷贝,拷贝构造函数也将被调用,如下例
CTest func()
{
 CTest theTest;
 return theTest;  //调用了拷贝构造函数
}
3.定义变量时直接赋值调用拷贝构造函数
CTest theTest;
CTest test2 = theTest; //调用了拷贝构造函数,即使重载了=运算符,此处也是调用拷贝构造函数
上面的调用等价于 CTest test2(theTest);//显示调用拷贝构造函数
1.拷贝构造函数在以下情况中必须要实现
原则上,应该为所有包含动态分配成员的类都提供拷贝构造函数
还有依照C++教材的说明,默认拷贝构造函数不能实现的必须要实现拷贝构造函数
拷贝构造函数的格式为:构造函数名(对象的引用)
CTest(const CTest &test);//参照如此格式

再介绍=运算符的重载

1.在必须要实现拷贝构造函数的情况下也必须要实现=运算符,这很重要,很多情况下我们没有实现=运算符,但在工作中使用了,
   好像没有问题,但我们使用的是默认的=运算符,这就隐藏了内存错误.参考拷贝构造函数的说明
  =运算符的格式
const CMyCString &operator =(const CMyCString &Src);//最好使用引用,这样是为了不调用拷贝构造函数
=运算符返回引用是为了下面的运算
a=b=c=d

菊子曰 本文用菊子曰发布
原创粉丝点击