1.定义
(1)构造函数:
定义对象的时候,自动调用当前类的构造函数
如果程序员没有定义构造函数,则类会提供一个默认的构造函数,给类中的数据成员分配空间(分配的栈空间)
(2)特点:
特殊的成员函数,函数名和类名相同,无返回类型,可以带参数(可以重载)
class Table
{
public:
void Set();
void Print();
private:
int m_length;
int m_width;
int m_height;
};
void Table::Set()
{
m_length = 120;
m_width = 40;
m_height = 80;
}
void Table::Print()
{
cout << m_length << " " << m_width << " " << m_height << endl;
}
void main()
{
Table t;//自动调用了构造函数(已开辟空间)
t.Set();
t.Print();
}
2.调用构造函数顺序
遇到对象,要自动调用当前类的构造函数。
(1)顺序
(1)传参
(2)根据数据成员在类中的声明顺序开辟空间
(3)执行构造函数函数体
class Table
{
public:
Table(int l=120,int w=40,int h=80)//默认构造函数,无参,无返回类型
{
m_length = l;
m_width = w;
m_height = h;
cout << "Table" << endl;//调用提示
}
void Print()//void 函数不返回值
{
cout << m_length << " " << m_width << " " << m_height << endl;
}
private:
int m_length;
int m_width;
int m_height;
};
void main()
{
Table t;//定义函数,自动调用了构造函数(已开辟空间)
t.Print();
Table t1(60);
t1.Print();
Table t2(180,50,90);
t2.Print();
Table tt[5];//对象数组,调用五次构造函数
//Table* p;//不会调用构造函数,在栈上开辟了4字节,并没有定义一个对象,只是指向Table类型的一个指针,野指针 很危险
Table* p = &t;
p->Print();
}
(2).调用顺序第二点注意点及例题
根据数据成员在类中的声明顺序,用冒号语法后面的值进行初始化
class A
{
public:
A(int i = 0, int j = 0) :m_j(j), m_i(m_j)//根据声明顺序,m_j还没有值,所以为随机值
{
}
void Print()
{
cout << m_i << " " << m_j << endl;
}
private:
int m_i;
int m_j;
};
void main()
{
A a(4, 8);// 随机值 8
a.Print();
}
3.组合
强拥有,一个类的对象作为另一个类的数据成员,整体和部分的关系
class CPU
{
public:
CPU()
{
cout << "CPU" << endl;
}
};
class Mouse
{
public:
Mouse()
{
cout << "Mouse" << endl;
}
};
class KeyBoard
{
public:
KeyBoard()
{
cout << "KeyBoard" << endl;
}
};
class Computer
{
public:
Computer()
{
cout << "Computer" << endl;
}
private://类的组合
CPU cpu;
Mouse ms;
KeyBoard kb;
};
void main()
{
Computer c;
}
4.冒号语法
(1)引出冒号语法
类成员初始化的困惑--冒号语法--成员初始化列表
class Date
{
public:
Date(int y=2000, int m=1, int d=1)//若不想给定初始值,直接传入可使用冒号语法
{
m_y = y;
m_m = m;
m_d = d;
cout << "Date" << m_y << " " << m_m << " " << m_d << endl;
}
void Show()
{
cout << m_y << " " << m_m << " " << m_d << endl;
}
private:
int m_y;
int m_m;
int m_d;
};
class Student
{
public:
Student(int num,const char* name, Date d)
{
m_num = num;
strcpy(m_name, name);
birthday = d;
}
void Print()
{
cout << m_num << " " << m_name << " ";
//cout << birthday << endl;
birthday.Show();
}
private:
int m_num;
char m_name[20];
Date birthday;
};
void main()
{
Date d(2002, 11, 9);
Student s(1001, "tjs", d);
s.Print();
}
(2)冒号语法使用如下:
class Date
{
public:
Date(int y, int m, int d):m_y(y),m_m(m),m_d(d)
{
/*m_y = y;
m_m = m;
m_d = d;
cout << "Date" << m_y << " " << m_m << " " << m_d << endl;*/
}
void Show()
{
cout << m_y << " " << m_m << " " << m_d << endl;
}
private:
int m_y;
int m_m;
int m_d;
};
class Student
{
public:
//Student(int num, const char* name, Date d):birthday(d)
Student(int num, const char* name, int y,int m,int d):m_num(num),birthday(y,m,d)
{
//m_num = num;
strcpy_s(m_name, name);
//birthday = d;
}
void Print()
{
cout << m_num << " " << m_name << " ";
//cout << birthday << endl;
birthday.Show();
}
private://声明顺序
int m_num;
char m_name[20];
Date birthday;
};
void main()
{
//Date d(2002, 11, 9);
//Student s(1001, "lisi", d);
Student s(1001, "tjs", 2002, 11, 9);
s.Print();
}
(3)冒号语法出现的原因及注意
1.类成员初始化的困惑
2.常量和引用只能使用冒号语法进行初始化
3.set是设置函数,不能初始化
4.后面只能用(),并且中间用,“,”
class A
{
public:
A(int i, int j) :m_i(i), m_j(j)
{
}
private:
const int m_i;//不能在这初始化
int& m_j;//引用
};
void main()
{
//const int a;需初始化数值
//a = 7;a值不能改变
//int a = 10;
//int& b;引用必须初始化
//b = a;
}
5.相关笔试题
main 函数之前是否可以执行一段代码,如果可以,请举例
class A
{
public:
A()
{
cout << "A" << endl;
}
};
A a;//全局对象
void main()
{
cout << "main" << endl;
}