类的数据成员是不能在声明的时候初始化的,因为类并不是一个实体,而是一种抽象类型,并不占用内存空间,显然无法容纳数据。
如果一个类的成员都是共有的,则可以这样定义:
#include <iostream>
using namespace std;
class A
{
public:
int a_, b_, c_;
void display()
{
cout<<a_<<" "<<b_<<" "<<c_<<endl;
}
};
int main()
{
A a={1,2,3}; //一般都不这样,这样破坏了类的封装
a.display();
return 0;
}
构造函数是一种特殊的成员函数,与其他成员函数不同,不需要用户来调用,而是在建立对象时自动执行。保证类的每个成员变量都能正确的初始化。
构造函数的名字必须与类名相同,无返回值类型
注意:
(1)在类对象进入作用域时调用构造函数
(2)构造函数没有返回值,因此不需要再定义构造函数时声明类型,void也不要
(3)不能被用户调用,系统自动调用。
(4)一般构造函数定义为public,也有private(比如singleton模式)
(5)如果用户没有定义构造函数,系统会默认添加一个空的无参的构造函数,一旦用户定义了,系统就不会提供
(6)可以有任意个数的参数,可以重载
(7)默认参数的构造函数最好不要和构造函数的重载一块使用,以免产生二义性
析构函数:当对象的生命周期结束时,会自动执行析构函数。
无返回值,无参数,无函数类型,由于没有参数,所以就不能被重载。
析构函数可以显式的调用
一般情况下:先构造的后析构,后构造的先析构,具体情况还要看对象的作用域
#include <iostream>
using namespace std;
class Time
{
public:
Time()
{
hour_ = 0;
minute_ = 0;
second_ = 0;
cout<<"Init"<<" "<<hour_<<endl;
}
Time(int hour) //构造函数重载
{
hour_ =hour;
minute_ = 0;
second_ = 0;
cout<<"Init"<<" "<<hour_<<endl;
}
Time(int hour, int minute):hour_(hour),minute_(minute),second_(0) //初始化列表,对const成员必须使用初始化列表初始化
{
cout<<"Init"<<" "<<hour_<<endl;
}
Time(int hour, int minute, int second) //构造函数的重载
{
hour_ = hour;
minute_ = minute;
second_ = second;
cout<<"Init"<<" "<<hour_<<endl;
}
~Time()
{
cout<<"destoryed"<<" "<<hour_<<endl;
}
private:
int hour_;
int minute_;
int second_;
};
Time T4(30); //Init 30 ,先于main函数
int main()
{
cout<<"begin main"<<endl;
Time t; //Init 0说明构造函数是自动调用的
Time t5(); //error不是创建对象的方式 虽然不报错,但是这句是不调用构造函数的,这句的意思是声明了一个普通函t5,返回值类型为Time
Time t1(12,12,12); //Init 12
Time *t2 = new Time(10); //Init 10调用构造函数,()是传参
Time *t3 = new Time[3]; //定义一个包含三个Time类的数组 【】是数组元素个数
//Time a[3] = {12,12,12}; //容易引起歧义,最好不要这样定义
//t.Time(); //构造函数不能显示的调用,且每个对象只能调用一次构造函数
delete t2;
delete[] t3;
cout<<"main end"<<endl;
return 0;
}
程序运行结果见下图