class Clock{
public: //函数成员
void setTime(int newH , int newM , int newS);
void showTime();
private: //数据成员
int hour , minute , second;
};
4.2.3对象
Clock myclock; //定义一个myclock对象 myclock.setTime(2 , 3 , 4); //调用函数成员4.2.4类的成员函数
1、成员函数的实现
#includeusing namespace std; class Clock{ public: //函数成员 void setTime(int newH , int newM , int newS); void showTime(); private: //数据成员 int hour , minute , second; }; void Clock::setTime(int newH , int newM , int newS) //成员函数在类外实现 { hour = newH; minute = newM; second = newS; } void Clock::showTime() { cout << hour << ":" << minute << ":" << second << endl; } int main() { Clock myclock; //定义一个myclock对象 myclock.setTime(2 , 3 , 4); //调用函数成员 myclock.showTime(); return 0; }
2、成员函数调用中的目的对象
在类的成员函数中,既可以访问目的对象的私有成员,又可以访问当前类的其他对象的私成员,
3、带默认形参值的成员函数
4、内联成员函数
减少调用开销,提高执行效率,
inline void Clock::showTime()
{
cout << hour << ":" << minute << ":" << second << endl;
}
4.3构造函数和析构函数
在定义对象的时候进行数据成员设置,称为对象的初始化,
在c++中对象的 初始化和清理工作,由两个函数,构造函数和析构函数来完成,
4.3.1构造函数初始化程序,
作用:在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态,
特征:类的一个公有成员函数;函数名与类名相同,并没有返回值;
调用时无须提供参数的构造函数称为默认构造函数。
如果没有写构造函数,系统自己生成默认构造函数,若写,则不会生成,这样就不能使用无参的调用,除非在写一个构造函数(重载)。
class Clock{
public: //函数成员
Clock(){ } //默认构造函数
};
#include4.3.2默认构造函数using namespace std; class Clock{ public: //函数成员 Clock(int newH , int newM , int newS);//构造函数 Clock();//函数重载,构造无参初始函数 void setTime(int newH , int newM , int newS); void showTime(); private: //数据成员 int hour , minute , second; }; void Clock::setTime(int newH , int newM , int newS) { hour = newH; minute = newM; second = newS; } inline void Clock::showTime() { cout << hour << ":" << minute << ":" << second << endl; } Clock::Clock(int newH , int newM , int newS):hour(newH),minute(newM),second(newS) { } //等价于 //Clock::Clock(int n , int m , int s) //{ // ni = n ; // mi = m; // si = s; //} int main() { Clock myclock(2 , 3 , 4); //初始化myclock对象 myclock.showTime(); Clock c; //myclock对象 c.setTime(1 , 2 , 3); c.showTime(); return 0; }
#include4.3.3委托构造函数using namespace std; class Clock{ public: //1.构造方法 Clock(int n , int m , int s); Clock();//无参构造方法 void settime(int n , int m , int s); void showtime(); private: int ni , mi , si; }; //2.类外实现函数内部 void Clock::settime(int n , int m , int s) { ni = n; mi = m; si = s; } inline void Clock::showtime() { cout << ni << " " << mi << " " << si << endl; } //3.类外实现构造函数内部, Clock::Clock(int n , int m , int s): ni(n) , mi(m) , si(s) { } //4.实现无参构造函数的初始化 Clock::Clock():ni(1) , mi(2) , si(3){ } int main() { Clock m(2 , 3 , 4); //有参构造 m.showtime(); Clock c; //无参构造,已给定初始值 c.showtime(); return 0; } 2 3 4 1 2 3
建立在构造函数上的构造函数,
委托构造函数使用类中其他的构造函数执行它自己的初始化过程,
#includeusing namespace std; class Clock{ public: //1.构造方法 Clock(int n , int m , int s); Clock();//无参构造方法 void settime(int n , int m , int s); void showtime(); private: int ni , mi , si; }; //2.类外实现函数内部 void Clock::settime(int n , int m , int s) { ni = n; mi = m; si = s; } inline void Clock::showtime() { cout << ni << " " << mi << " " << si << endl; } //3.类外实现构造函数内部, Clock::Clock(int n , int m , int s): ni(n) , mi(m) , si(s) //构造函数(被委托) { } //4.通过委托构造函数实现无参构造函数的初始化 Clock::Clock(): Clock(1 , 2 , 4){ //构造函数(委托) //先执行被委托的构造函数,然后再执行委托构造函数 //就是通过被委托的构造函数进行初始化, } int main() { Clock m(2 , 3 , 4); //有参构造 m.showtime(); Clock c; //无参构造,已给定初始值 c.showtime(); return 0; } 2 3 4 1 2 4
//3.类外实现构造函数内部,
Clock::Clock(int n , int m , int s): ni(n) , mi(m) , si(s) //构造函数(被委托)
{
}
//4.通过委托构造函数实现无参构造函数的初始化
Clock::Clock(): Clock(1 , 2 , 4){ //构造函数(委托)
//先执行被委托的构造函数,然后再执行委托构造函数
//就是通过被委托的构造函数进行初始化,
}
4.3.4复制构造函数
对 对象的复制,克隆,如要复制一份a对象的副本,那么就需要新创建一个对象b然后将a的所有数据成员取出来,一一赋值给b对象,这样就很麻烦,
在此提供一种特殊的构造函数,复制构造函数,
其形参是本类的对象引用,其作用是使用一个已经存在的对象(由复制构造函数的参数指定),去初始化同类的一个新对象。
如果没有自己定义复制构造函数,系统会自动生成一个隐含的复制构造函数,
隐含的复制构造函数的功能是,把初始值对象的每一个数据成员的值都复制到新建立的对象中,因此就完成了同类对象的克隆。
class Point{
public:
//1.构造函数
Point(int xx ,int yy);
//2.复制构造函数
Point(Point &p);
//3.get返回私有属性
int getX(){ return x;}
int getY(){ return y;}
private:
int x , y;
};
//4.构造函数
Point::Point(int xx ,int yy){
x = xx , y = yy;
}
//5.复制构造函数
Point::Point(Point &p){
x = p.x , y = p.y;
cout << " 这是复制的对象 " << endl;
}
复制构造函数被调用的情况:
(1)当用类的一个对象去初始化该类的另一个对象时
int main()
{
Point a(1 ,2);
Point b(a); //用对象a初始化对象b
Point c = a; //用对象a初始化对象c
cout << b.getX() <<" " << c.getY() << endl;
return 0;
}
这是复制的对象
这是复制的对象
1 2
(2)如果函数的形参是类的对象,调用函数时,进行形参和实参的结合
void f(Point p){
cout << p.getX() << endl;
}
int main()
{
Point a(1 ,2);
f(a);
return 0;
}
(3)如果函数的返回值是类的对象,函数执行完成后
Point g(){
Point a(1 , 2);
return a; //返回时调用复制构造函数
}
int main()
{
Point b;
b = g();
cout << b.getX() << endl;
return 0;
}
#includeusing namespace std; class Point{ public: //1.构造函数 Point(int xx ,int yy); Point(){} //2.复制构造函数 Point(Point &p); //3.get返回私有属性 int getX(){ return x;} int getY(){ return y;} private: int x , y; }; //4.构造函数 Point::Point(int xx ,int yy){ x = xx , y = yy; } //5.复制构造函数 Point::Point(Point &p){ x = p.x , y = p.y; cout <<" 这是复制的对象 " << endl; } Point g(){ Point a(1 , 2); return a; //返回时调用复制构造函数 } int main() { Point b; b = g(); cout << b.getX() << endl; return 0; } 1
其实系统会直接自动生成隐含复制函数,不用额外定义,但如果想只复制一部分就需要自己定义。
4.3.5析构函数用来完成对象被删除前的一些清理工作,在调用析构函数后,对象小时,对应的内存空间也被释放。
析构函数通常也是类的公有函数成员,
由类名前面加“~”构成,没有返回值,也没有任何参数,系统自动生成,
class Point{
public:
//1.构造函数
Point(int xx ,int yy);
Point(){}
//2.复制构造函数
Point(Point &p);
//3.get返回私有属性
int getX(){ return x;}
int getY(){ return y;}
//4.析构函数
~Point(){}
private:
int x , y;
};
4.3.7default/delete函数
class Point{
public:
//1.构造函数
Point(int xx ,int yy);
Point() = default;//(只能)默认合成无参构造函数
//2.复制构造函数
Point(Point &p) = default; //默认合成复制构造函数
//3.get返回私有属性
int getX(){ return x;}
int getY(){ return y;}
//4.析构函数
~Point() = default; //默认合成析构函数
private:
int x , y;
};
使用=default可以显示要求编译器自动生成默认或复制构造函数,以及析构函数。
class Point{
public:
//1.构造函数
Point(int xx ,int yy);
Point() = delete;//删除合成无参构造函数
//2.复制构造函数
Point(Point &p) = delete; //删除合成复制构造函数
//3.get返回私有属性
int getX(){ return x;}
int getY(){ return y;}
//4.析构函数
~Point() = default; //默认合成析构函数
private:
int x , y;
};
delete,除析构函数外,用户可以随意指定为delete删除掉,
4.4类的组合就是类的镶嵌
#include#include using namespace std; class Point{ public: //1.构造函数 Point(int xx ,int yy); //2.复制构造函数 // Point(Point &p); //3.get返回私有属性 int getX(){ return x;} int getY(){ return y;} //4.析构函数 ~Point() = default; //默认合成析构函数 private: int x , y; }; //4.构造函数 Point::Point(int xx ,int yy){ x = xx , y = yy; } 5.复制构造函数 //Point::Point(Point &p){ // x = p.x , y = p.y; //} //6.类的组合 class Line{ public: Line(Point xp1 , Point xp2); // Line(Line &l); double getLen(){ return len; } private: Point p1, p2; double len; }; //7.组合类的构造函数 Line::Line(Point xp1 , Point xp2):p1(xp1) , p2(xp2){ double x = static_cast (p1.getX() - p2.getX()); double y = static_cast (p1.getY() - p2.getY()); len = sqrt(x * x + y * y); } 8.组合类的复制构造函数 //Line::Line(Line & l) : p1(l.p1) , p2(l.p2){ // len = l.len; //} int main() { Point a(1 , 1) , b(4 ,5); Line line(a , b); cout << "The length of the line is "; cout << line.getLen(); return 0; } The length of the line is 5
复制构造函数一般程序自带



