C++中构造函数的那点事

来源:互联网 发布:华为mate8软件搬家 编辑:程序博客网 时间:2024/05/05 05:08
C++中构造函数的那点事
Last Edit 2013/11/22
一般的构造函数,这里就不提了。主要记录几种特殊的情况:
1.类中内嵌其他类的对象,构造函数的写法;
2.类与类相互包含时,怎么处理;
3.同类对象之间的赋值,浅拷贝与深拷贝

情况1:
 如果在一个类中内嵌了其他类的对象,那么创建这个类的对象时,其中的内嵌对象也会被自动创建。因为内嵌对象是组合类的对象的一部分,所以在构造组合类的对象时不但要对基本数据类型的成员进行初始化,还要对内嵌对象成员进行初始化。

类名::类名(形参表):内嵌对象1(形参表),内嵌对象2(形参表),...
       {
                 类的初始化
       }
下面看一个例子
 #include <iostream>       using namespace std;       class Point       {        public:                 Point(int xx,int yy)   { X=xx; Y=yy; } //构造函数                 Point(Point &p);                 int GetX(void)     { return X; }        //取X坐标                 int GetY(void)     { return Y; } //取Y坐标       private:                 int X,Y; //点的坐标       };       Point::Point(Point &p)       {                 X = p.X;                 Y = p.Y;                 cout << "Point拷贝构造函数被调用" << endl;       }       class Distance       {       public:                Distance(Point a,Point b); //构造函数                double GetDis()   { return dist; }       private:                Point  p1,p2;                double dist;               // 距离        };        // 组合类的构造函数        Distance::Distance(Point a, Point b):p1(a),p2(b)   //Attention        {                cout << "Distance构造函数被调用" << endl;                double x = double(p1.GetX() - p2.GetX());                double y = double(p1.GetY() - p2.GetY());                dist = sqrt(x*x + y*y);                return;        }        int _tmain(int argc, _TCHAR* argv[])        {               Point myp1(1,1), myp2(4,5);               Distance myd(myp1, myp2);               cout << "The distance is:";               cout << myd.GetDis() << endl;               return 0;        }
情况2:先看一下这个例子
比如,类A的公有成员函数f的形参是类B的对象,同时类B的公有成员函数g的形参是类A的对象,这时就必须使用前向引用声明:       class B;  //前向引用声明       class A       {         public:                   void f(B b);       };       class B       {         public:                  void g(A a);       };
这个情况在MFC文档视图工程创建时容易出现报错,就是因为文档类与视图类相互包含导致的,出现如下报错信息

c:\documents and settings\chenqi\桌面\guo\guoview.h(23) :error C2143: syntax error : missing ';' before '*'

c:\documents and settings\chenqi\桌面\guo\guoview.h(23) :error C2501: 'CGuoDoc' : missing storage-class or type specifiers

c:\documents and settings\chenqi\桌面\guo\guoview.h(23) :error C2501: 'GetDocument' : missing storage-class or type specifiers

只要在View类的头文件中加入 class ..doc,问题就可以解决。


情况3:

#include <iostream>using namespace std; class CExample {private:     int a;public:     CExample(int b)     { a=b;}     void Show ()     {        cout<<a<<endl;      }}; int main(){     CExample A(100);     CExample B=A;    //Attention     B.Show ();     return 0;} 
程序中:系统为对象B分配了内存并完成了与对象A的复制过程,相同类型的类对象是通过拷贝构造函数来完成整个复制过程的

1)什么时候用到拷贝函数?

  a.一个对象以值传递的方式传入函数体; 
  b.一个对象以值传递的方式从函数返回;
  c.一个对象需要通过另外一个对象进行初始化。

如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。位拷贝又称浅拷贝

2)浅拷贝会出现什么问题。

     当B中的变量申请了指针变量指向A中内存变量时,B对象析构时,会使得A中指针悬挂,内存泄漏。

3)深拷贝

     深拷贝就是在拷贝函数中实现完全复制

CA(const CA& C)  {   a=C.a;   str=new char[a]; //深拷贝   if(str!=0)    strcpy(str,C.str);  }