幽魂国度

 

构造函数简介

目的:为了使用户定义的数据类型如同一般数据类型一样使用。
功能:对对象进行初始化,有若干种方法。
特点:1、无返回值说明;2、不能继承;3、可以有缺省参数;4、不能取地址,构造时自动给对象分配栈中内存,析构时回收;
            5、自动调用构造函数。
        构造函数是类的一个特殊成员函数,其函数名同类名一样。C++通过构造函数可以正确地初始化对象。构造函数不能被显式调用,不能使
虚函数。
例: class queue {
                         int q[100];              //默认为private
                         int sloc,rloc;
                      public:
                         queue();
                         void qput(int i); 
};
queue ::queue ()          //隐式调用
{
        sloc=rloc=0;
}        
int    queue ::qput (int i){}
main()
{
      queue  a,b;
      a.qput (10); 
      b.qput (20); 
}
      参数化的构造函数
queue ::queue (int vx,int vy){} };
main()
{
    queue  a(10,20);
}
      缺省参数的构造函数:特殊情况下需要传递参数,一般都是用缺省参数。
单个参数:queue ::queue (int i=16) {}   };
                    main()
                      {
                             queue  a;
                       }
多个参数:queue ::queue (int vx=0,int vy=0) {}
缺省参数还可用于一般成员函数。使用时应注意避免二义性。
      多构造函数
public:
        queue ( );
        queue (int );
        queue (int,char );
};
main()
{
         queue a;
         queue b(1);
         queue c(1,'c');    //避免二义性
}
       拷贝构造函数
1、系统产生:
queue ::queue (int vx,int vy){}   };
  main() { queue a(b) ; }
2、自定义:
queue ::queue (const queue &p){}  };
 main()  { queue }

总结:构造函数的作用是对对象本身做初始化工作,也就是给用户提供初始化类中成员变量的一种方式。
          如果一个类中没有定义任何的构造函数,那C++编辑器将在某些情况下提供一个默认的构造函数(不带参数),3种情况:
    1)、类有虚拟成员函数或虚拟继承父类(虚拟基类);
    2)、类的基类有构造函数;
    3)、类中的所有非静态饿对象数据成员,它们所属的类中有构造函数。

构造函数的目的是为了初始化对象,因此一个构造函数至少应该使得对象处于明确定义的状态
例://class string
string () {s=new char[80];len=80;}
string (int n) {s=new char[n];len=n;}
}
string::stringprintf() { cout<< s <<endl;}
定义对象:
string x,y(80);
x.print();
y.print();
此时,x和y调用的print()函数结构未定义,因为在构造函数中只对字符数组分配了内存,却未对分配的内存进行初始化。
我们可以通过修改带默认参数值的构造函数来改进:
string (int n=80) {s=new char[n];s[0]='\0';len=n;}
 用默认参数的形式来代替函数重载的形式。

注意点:
1)构造函数应该使对象处于明确定义的状态;
2)保持物理状态的一致性:对数据成员的定义保持一致,在所有函数中只能使用一种定义。
3)类不变性:可以将不变性作为程序代码的注释,//len=strlen(s);
4)动态内存的一致性:接口一致性
     void assign (char* str) { strcpy(s,str);}
     void concat (string& a) {s=new char[len+1];strcpy(s,a.s);}
     两函数的表现行为存在不一致性:前者内存不再分配,而后者一直在分配。我们应只使用一种以保持一致性。
5)内存泄露:concat函数中每拷贝一次,s就重新分配一次,s被新的指针值覆盖,而前一指针值被抛弃,产生内存垃圾。
      因此concat函数必须保证旧的数组一定要被删除,对于每一个new,就必须有一个delete操作,且delete语句只能被增加在
      新的字符串创建之后。
      void concat (string& a) {new_s=new char[len+1];strcpy(s,a.s); delete[]s;s=new_s;}

posted on 2009-11-10 15:49 阅读(434) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

常用链接

留言簿

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜