#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using namespace std;//有分号;
class Point//这里类的名称首字母一般大写
{
private:
int x_;//默认函数内部,private函数中定义的变量最好是有一个"_",书写方式要记住;
int y_;
public://这里用到了重载构造函数和析构函数,重载构造函数和析构函数一般是在一起的。
Point():x_(0),y_(0)//构造函数 详细见下一;
{
cout<<"construct pooint:"<<x_<<" "<<y_<<endl;
}
Point(int x):x_(x),y_(x)//初始化列表 详见下二;
{
cout<<"construct pooint:"<<x_<<" "<<y_<<endl;
}
Point(int x,int y):x_(x),y_(y)
{
cout<<"construct pooint:"<<x_<<" "<<y_<<endl;
}
~Point()//析构函数 详见下三;
{
cout<<"destroy pooint:"<<x_<<" "<<y_<<endl;
}
public:
int getx()const//常量成员函数 详见下四;
{
x_=1;//错误,因为函数是只读的,不能对函数里面的内容进行修改;
return x_;
}
int gety()const
{
return y_;
}
int setx(int x)
{
x_=x;
}
int sety(int y)
{
y_=y;
}
int setxy(int x,int y)
{
x_=x,y_=y;
}
};
int main()
{
Point p1;
Point p2(6);
{
Point p3(7,8);
}
Point p4(2,3);
Point p5[5];
return 0;
}
一、构造函数:作用是初始化;
- (1)形式
class X
{
X(){}
};
例如:
class Point
{
private:
int x_,y_;
public:
Point(int x,int y):x_(x),y_(y)
{
cout<<"construct pooint:"<<x_<<" "<<y_<<endl;
}
};
int main()
{
Point p1(2,3);
return 0;
}
(2)声明
class X
{
X();
};
X::X()
{
}
例如:
class Point
{
private:
int x_,y_;
public:
Point(int x,int y);
};
Point::Point(int x,int y):x_(x),y_(y)
{
cout<<"construct pooint:"<<x_<<" "<<y_<<endl;
}
int main()
{
Point p1(2,3);
return 0;
}
2、特点
(1)是与类同名,并且没有返回类型。
(2)可以被重载。
(3)由系统自动调用,不允许被显示调用。
(4)构造函数不能被声明为const函数。
3、默认构造函数
原来的函数没有构造函数时,系统会自动生成默认构造函数,因为c++每一个类中必须要有构造函数。在这种情况下,如果要无参对象,必须显示定义无参构造函数。
注意:在形式定义构造函数之后就不会再创建合成默认构造函数了。
public:
//Point():x_(0),y_(0)
//{
cout<<"construct pooint:"<<x_<<" "<<y_<<endl;
//}
Point(int x):x_(x),y_(x)
{
cout<<"construct pooint:"<<x_<<" "<<y_<<endl;
}
};
int main()
{
Point p1;
point p2(2);
}
如果将第一个Point注释掉,又因为显示定义了一个构造函数,那么就会没有默认构造函数,这样p1的值将是乱码,因为没有给p1赋初值。
如果没有显示构造函数的话,p1的值就会由默认构造函数决定为0、0。
4、重载构造函数
与函数重载一样,参数的个数、参数的类型、参数的顺序三者之一必须不同。
二、参数列表
1、形式
构造函数名(参数列表):成员函数1(初值),成员函数2(初值)
{
}
除了最上面的代码之外,还有一个例子
Point(double image):image_(image){}//因为仅仅为了赋初值所以{}里面没有内容。
2、几种赋初始值的形式
class Tdate
{
public:
Tdate(int month,int day,int year);
protected:
int day_,month_,year_=30;//这样是类内初始值;
};
Tdate::Tdate(int month,int day,int yeat):month_(month)
{
day_=day;
}
**其中year采用类内初始值,day采用普通函数的初始化方式,month采用初始化列表的形式。**
3、函数执行顺序
类内初始值 然后 构造函数初始化列表 然后 构造函数体
4、注意
使用参数列表的前提是在构造函数中,在类里面的其他函数中是不能这样赋初值的,只有构造函数中才能这样赋初值。
三、析构函数
1、(1)形式
class X
{
public:
~x(){}
};
(2)声明
class X
{
public:
~x();
};
x::~x()
{
}
2、作用:用于对象生存期结束时,完成对象的清理工作。
3、特点
(1)析构函数的名字就是在类名前面加一个~,不能有其余的名字。
(2)析构函数没有返回类型,没有参数列表。
(3)析构函数不能重载,一个函数只能有一个析构函数。
(4)析构函数只能由系统自动调用,不能显示调用析构函数。
(5)每个类都应有一个析构函数,如果没有显示调用析构函数的话,系统会自动调用析构函数。
4、说明
(1)若有多个对象同时结束生存期,将按照相反的顺序调用析构函数。
注意:一个大括号结束即一个生存期结束。
int main()
{
Point p1;
Point p2(6);
{
Point p3(7,8);
}
Point p4(2,3);
Point p5[5];
return 0;
}
四、常量成员函数
1、(1)形式
class X
{
public:
函数返回类型 函数名(参数类型 参数,参数类型 参数,等等)const
{
}
};
(2)声明
class X
{
public:
函数返回类型 函数名(参数类型 参数,参数类型 参数,等等)const;
};
函数返回类型 X::函数名(参数类型 参数,参数类型 参数,等等)
{
}
2、作用:为了禁止成员函数修改数据成员的值
3、特点:
(1)只有类的成员函数才能定义为常量函数,普通函数不能定义为常量函数。
(2)常量参数与常量函数是有区别的,常量参数限制函数对参数的修改,但与数据成员是否被修改无关。(所谓的数据成员就是类中直接定义的变量。)
例如:
class Point
{
private:
int x_,y_;
public:
int getx()const
{
x_=1;//错误,因为改变了类中的变量;
return x_;
}
};
五、内联函数
1、形式
class Date
{
private:
int day_,month_,year_;
public:
void init(int d,int m,int y);//1
int getDay
{
return day_;
}
inline int getMonth();//2
};
inline void Date::init(int d,int m,int y)//1
{
day_=d;
month_=m;
year_=y;
}
int Date::getMonth()//2
{
return month_;
}
1与2是调用内联函数的两种形式。一个是在类里面就说明为内联函数,一个是在类内声明,在类外说明是内联函数。
2、在类外定义成员函数,也就是在类里面仅仅声明,在类外说明的时候,所有类型都要一致,并且要加::间隔。