1、对象数组
结构体数组
数组中所有的元素都是同一结构体类型的变量。
对象数组
数组中所有的元素都是同一类定义的对象。
对象数组的初始化
1.必须要有与初始化方式匹配的构造函数。
2.如果需要调用构造函数初始化,请指明哪个构造函数。
2、this指针
C++提供了一个隐藏的对象指针 -- this指针。
每一个类的成员函数都有一个隐藏的指针参数,其名称为this,类型为当前类的类型。这个隐藏的参数是该成员函数的第一个参数。
C++编译时会对成员函数和成员函数的形式进行改变、
1.隐藏参数为this
void fun(stu *this)
2.成员函数中的数据成员皆为this->的成员
this->id
3.调用该成员函数对象须将地址传入该函数
s1.print() ---> print(&s1);
this指针的用法:
1.当成员函数的形参与数据成员重名时,可以使用this指针区分数据成员和形参。
2.某个成员函数返回调用该成员函数对象本身(引用)。 如果在某个对象调用完一个成员函数后紧接着通过该对象继续调用下个成员函数,可以通过this指针实现连续调用。要求第一个函数其返回值为当前类的对象的引用,并在函数内返回*this;
3、只能在类中使用的常量:
1.const修饰的数据成员
a.const修饰的数据成员只能使用构造函数列表进行初始化
b.const修饰的数据成员在不同对象中其值可以不同。
2.枚举
在类中定义枚举类型,该类型只能在类中使用。
4、静态成员
1.静态数据成员
a.不管定义多少个对象,静态数据成员有且只有一份,所有的对象共同使用同一个静态数据成员;静态数据成员属于类,而不是属于某个对象独有。
b.静态数据成员是在类外定义,类内加上static声明。
c.静态数据成员可以使用类名进行访问,也可以使用对象进行访问
stu::id ,stu s1 s1.id
d.静态成员不占用对象的内存,存储在静态全局区
静态数据的作用:
1.实现了多个对象的数据共通。
2.可以代替全局变量的使用。
2.静态成员函数
a.使用static修饰的成员函数就是静态成员函数
b.静态成员函数属于整个类,不是某个对象
c.因为静态成员函数没有this指针,所以静态成员函数只能访问静态成员、全局变量。
5.对象成员
对象成员也是成员,只不过这个成员为另外一个类的对象。类的嵌套。
结构体嵌套
class a
{
public:
int num;
};
class b;
{
int num;
class a test;
};
b b1;
b1.num
b1.test.num;
对象成员的初始化必须使用构造函数列表完成。
没法直接访问当前类的对象成员的私有成员,只能通过公有成员函数间接访问。
一个类中有对象成员时,构造的顺序是先构造对象成员,再构造当前类的对象本身。析构顺序正好与之相反。
6.友元
一般来说,在类外无法访问类的私有成员,C++提供了一种机制友元可以在类外访问类的私有成员。
友元分为3种:友元函数,友元成员,友元类。
a.友元函数。一个类将另一个外部函数当做朋友,该外部函数可以访问该类的私有成员。
class a
{
friend void fun();
}
b.友元成员。一个类将另一个类的成员函数当做朋友。
c.友元类。一个类把另一个类当做朋友,作为朋友的类的所有成员函数可以访问该类所有私有成员。
友元类的声明方法是friend class 待声明为友元的类的名称。
注意:
1.尽量不要使用友元!
2.友元不是成员.友元不能使用this指针访问成员.只能通过传参方式访问成员
3.友元是单向的。A是B的朋友,但B不一定是A的朋友。
4.友元不具有传递性。A是B的朋友,B是C的朋友,但A不一定是C的朋友、
5.友元不具备继承性。
7.运算符重载
+ - * /算数运算符
<< >> 位运算符
int a;
int b;
a+b;
class A{};
class B{};
A a;B b; a+b;
运算符重载函数
将运算符当做函数,进行重载。
运算符重载的格式
返回值类型 operator 运算符(参数列表)
{
函数体
}
int operator + (A a1, A a2)
{
}
注意:
1.运算符重载后参数个数不允许发生改变。
2.重载后优先级也不会发生改变。
3.重载后运算符功能不能与之前的功能发生太大改变。+(s1-s2)
4.* :: ?: . sizeof()这几个运算符不允许重载
5.重载后的运算符参数必须至少有一个是自定义的数据类型。
例子
1.指向对像的指针
class Time
{
public:
int hour;
int minute;
int sec;
void get_time();
};
void Time::get_time()
{
cout << hour << ":" << minute << ":" << sec << endl;
}
在此有以下语句:
Time *pt;//定义pt 为指向Time类对像的指针变量 Time t1;//定义t1为Time类对像 pt=&t1;//将t1的起始地址赋给pt
这样,pt 就是指向Time类对象的指针变量,它指向对象t1。
定义指向类对象的指针变量的一般形式为:
类名 *对象指针名;
可以通过对象指针访问对象和对象的成员。如:
*pt pt所指向的对像,即t1 (*pt).hour pt所指向的对象中的hour成员,即t1.hour pt->get_time() pt把指向的对象中的get_time函数,即t1.get_time() (*pt).get_time()
2.指向对象成员的指针
a.指向对象数据成员的指针
定义指向对象数据成员的指针的方法与定主指向变通的指针变量的方法相同。如:
int *p;
定义指向对象数据成员的指针变量的一般形式为:
数据类型名 *指针变量名;
b.指向对象成员函数的指针
定义指向对象成员函数的指针变量的方法和定义指向变通函数的指针变量方法有所不同。
定义指向变通函数的指针变量的方法:
数据类型名 (*指针变量名)();如:
void (*p)();//p是指向void型函的指针变量
定义指向成员函的指针:
数据类型名 (类名::*指针变量名)();
使指针变量指向一个公用成员函数的一般形式为
指针变量名=&类名::成员函数名;
#include <iostream>
using namespace std;
class Time
{
public:
Time(int ,int ,int );
int hour;
int minute;
int sec;
void get_time();
};
Time::Time(int h,int m,int s)
{
hour = h;
minute= m;
sec = s;
}
void Time::get_time()
{
cout << hour << ":" << minute << ":" << sec << endl;
}
int main()
{
Time t1(10,13,56); //定义Time类对象t1
int *p1=&t1.hour;//定义指向整型数据的指针变量p1,并使p1指向t1.hour
cout << *p1 << endl;
t1.get_time();//调用对象t1的成员函数get_time()
Time *p2=&t1;//定义指向Time类对象的指针变量p2,并使p2指向t1
p2->get_time();//调用p2所指向对象的get_time()函数
void (Time::*p3)();//定义指向Time类公用成员函数get_time
p3 = &Time::get_time;//使p3指向Time类公用成员函数get_time
(t1.*p3)();//调用对象t1中p3所指的成员函数
return 0;
}
#include <iostream>
using namespace std;
class Time
{
public:
Time(int ,int ,int );
int hour;
int minute;
int sec;
void get_time();
};
Time::Time(int h,int m,int s)
{
hour = h;
minute= m;
sec = s;
}
void Time::get_time()
{
cout << hour << ":" << minute << ":" << sec << endl;
}
int main()
{
Time t1(10,13,56); //定义Time类对象t1
int *p1=&t1.hour;//定义指向整型数据的指针变量p1,并使p1指向t1.hour
cout << *p1 << endl;
t1.get_time();//调用对象t1的成员函数get_time()
Time *p2=&t1;//定义指向Time类对象的指针变量p2,并使p2指向t1
p2->get_time();//调用p2所指向对象的get_time()函数
void (Time::*p3)();//定义指向Time类公用成员函数get_time
p3 = &Time::get_time;//使p3指向Time类公用成员函数get_time
(t1.*p3)();//调用对象t1中p3所指的成员函数
return 0;
}