运行结果:
Date1 output: 1998.4.28 Date2 output: 2002.11.14 例2.18 关于计时器的例子 #include<iostream.h> #include<stdlib.h> class timer{ public: timer() // 无参数构造函数,给seconds清0 { seconds=0; } timer(char* t) // 含一个数字串参数的构造函数 { seconds=atoi(t); } timer(int t) // 含一个整型参数的构造函数 { seconds=t; } timer(int min,int sec) // 含两个整型参数的构造函数 { seconds=min*60+sec; } int gettime() { return seconds; } private: int seconds; }; main() { timer a,b(10),c("20"),d(1,10); cout<<"seconds1="<<a.gettime()<<endl; cout<<"seconds2="<<b.gettime()<<endl; cout<<"seconds3="<<c.gettime()<<endl; cout<<"seconds4="<<d.gettime()<<endl; return 0; } class x { public: x(); // 没有参数的构造函数 x(int i=0); // 带缺省参数的构造函数 }; //… void main() { x one(10); // 正确,调用x(int i=0) x two; // 存在二义性 //… } 3. 拷贝构造函数拷贝构造函数是一种特殊的构造函数,其形参是本类对象的引用。其作用是使用一个已经存在的对象去初始化另一个同类的对象。
通过等于号复制对象时,系统会自动调用拷贝构造函数。
拷贝构造函数与原来的构造函数实现了函数的重载。
拷贝构造函数具有以下特点:(1) 因为该函数也是一种构造函数,所以其函数名与类名相同,并且该函数也没有返回值类型。
(2) 该函数只有一个参数,并且是同类对象的引用。
(3) 每个类都必须有一个拷贝构造函数。程序员可以根据需要定义特定的拷贝构造函数,以实现同类对象之间数据成员的传递。如果程序员没有定义类的拷贝构造函数,系统就会自动生成产生一个缺省的拷贝构造函数。
3.1 自定义拷贝构造函数自定义拷贝构造函数的一般形式如下:
class 类名{ public : 类名(形参); //构造函数 类名(类名 &对象名); //拷贝构造函数 ... }; 类名:: 类名(类名 &对象名) //拷贝构造函数的实现 { 函数体 } 用户自定义拷贝构造函数 class Coord{ int x,y; public: Coord(int a, int b) // 构造函数 { x=a; y=b; cout<<"Using normal constructor\n"; } Coord(const Coord& p) // 拷贝构造函数 { x=2*p.x; y=2*p.y; cout<<"Using copy constructor\n"; } //… };如果p1、 p2为类Coord的两个对象,p1已经存在,则coord p2(p1)调用拷贝构造函数来初始化p2
例2.19 自定义拷贝构造函数的使用 #include<iostream.h> class Coord { public: Coord(int a,int b) // 构造函数 { x=a; y=b; cout<<"Using normal constructor\n";} Coord(const Coord& p) // 拷贝构造函数 { x=2*p.x; y=2*p.y; cout<<"Using copy constructor\n";} void print(){ cout<<x<<" "<<y<<endl; } private: int x,y; }; main() { Coord p1(30,40); // 定义对象p1,调用了普通的构造函数 Coord p2(p1); // 以“代入” 法调用拷贝构造函数,用对象p1初始化对象p2 p1.print(); p2.print(); return 0; }除了用代入法调用拷贝构造函数外,还可以采用赋值法调用拷贝构造函数,如:
main() { Coord p1(30,40); Coord p2=p1; //以"赋值"法调用拷贝构造函数, 用对象p1初始化对象p2 //… } 3.2 缺省的拷贝构造函数如果没有编写自定义的拷贝构造函数,C++会自动地将一个已存在的对象复制给新对象,这种按成员逐一复制的过程由是缺省拷贝构造函数自动完成的。
例2.20 调用缺省的拷贝构造函数 #include<iostream.h> class Coord{ public: Coord(int a,int b) { x=a; y=b; cout<<"Using normal constructor\n"; } void print(){ cout<<x<<" "<<y<<endl;} private: int x,y; }; main() { Coord p1(30,40); // 定义类Coord的对象p1, // 调用了普通构造函数初始化对象p1 Coord p2(p1); // 以“代入”法调用缺省的拷贝构造函数, // 用对象p1初始化对象p2 Coord p3=p1; // 以“赋值”法调用缺省的拷贝构造函数, // 用对象p1初始化对象p3 p1.print(); p2.print(); p3.print(); return 0; } 3.3 调用拷贝构造函数的三种情况(1) 当用类的一个对象去初始化该类的另一个对象时。
Coord p2(p1); // 用对象p1初始化对象p2, 拷贝构造函数被调用(代入法) Coord p3=p1; // 用对象p1初始化对象p3, 拷贝构造函数被调用(赋值法)(2) 当函数的形参是类的对象,调用函数,进行形参和实参结合时。
//… fun1(Coord p) // 函数的形参是类的对象 { p.print(); } main() { Coord p1(10,20); fun1(p1); // 当调用函数,进行形参和实参结合时, 调用拷贝构造函数 return 0; }