1 new \delete
new \delete运算符
1)作用:在堆上申请和释放内存
2)与mallo free比较
共同点 | 不同点 |
---|---|
都是向堆上申请和释放 内存 | malloc free是C语言标准库函数,有函数调用,有栈开销,new \delete是运算符,不需要栈开销,效率要高于malloc free |
new 和 delete会自动调用构造函数和析构函数 | |
delete 与 delete[]的他们区别在于:delete[]依次调用析构函数来释放堆内存 |
new、delete使用:
//类类型
Test t1(1,2);
Test t2(3,4);
Test* t = new Test[2]; //数组中在存放5个Test类的对象
// for(int i=0;i<2;i++)
// {
t[0] = t1; //简单赋值操作 不会调用拷贝构造函数,是因为没有去创建对象t[0]
t[1] = t2;
// }
t[0].printT();
t[1].printT();
if(t != NULL)
{
delete[] t; //delete 与 delete[]的他们区别在于:delete[]依次调用析构函数来释放堆内存
//free(t); //OK
t = NULL;
}
2 C++中友元
友元函数: 由关键字friend 开始的函数
友元好处:大大提高程序的效率,但是,不足之处,破坏了类的封装和隐藏的特性
1)类成员函数做为某个类的友元函数
friend int PointManager::cal_dis(Point& p1,Point& p2); //友元函数
//类的成员函数做为类的友元函数
int PointManager::cal_dis(Point& p1,Point& p2)
{
//this->dis = (p1.get_x()-p2.get_x())* (p1.get_x()-p2.get_x());
this->dis = (p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y); //可以把cal_dis做为Point类的友元函数
return this->dis;
}
2)全局函数做为某个类的友元函数
在类中声明为友元函数
//全局函数做为友元函数
friend int cal_dis(Point& p1,Point& p2);
//全局函数
int cal_dis(Point& p1,Point& p2)
{
//this->dis = (p1.get_x()-p2.get_x())* (p1.get_x()-p2.get_x());
int dis = (p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y); //可以把cal_dis做为Point类的友元函数
return dis;
}
3)友元类:把一个类声明为友元类
friend + 类的声明 ---- friend class Point;
class PointManager
{
public:
friend class Point;
int cal_dis(Point& p1,Point& p2);
void printP(Point& p)
{
cout << p.x << p.y << endl;
}
private:
int dis;
};
对于友元类,两个类之间要完全做到数据互通,则都需要设置对方为自己的友元类
总结:
1)友元关系不能被继承
2)友元关系是单向的,不具有交换性
3)友元关系不具有传递性
3 继承
引入继承的意义:提高代码的可重用性,减少代码冗余
类与类之间的关系: is-a has-a user-a
继承:is-a关系
has-a的关系:
class A
{
private:
B b; ---- has -a
};
user-a的关系:
class A
{
public:
void dis(B b) — user-a
};
继承方式:public \ protected \private
/*
继承方式
public protected private
基类 派生类 派生类 派生类
public public protected private
protected protected protected private
private 不可见 不可见 不可见
继承一般采用public继承
*/
3.1 单继承:派生类只一个基类
class 派生类:继承方式 基类名
{
};
子类中实现构造函数公式:
子类名(参数列表):成员变量(初始化参数),父类名1(参数列表),…父类名n(参数列表),内嵌子对象1(初始化参数)…内嵌子对象n(初始化参数)
UniversityMan(int age,char* name,char* skill):Student(age,name)//,t(t)
//相当于在子类中初始化了父类中的成员变量,所以一般在子类的构造函数中调用父类构造函数初始化父类中的成员变量
//this->age = age;
this->skill = (char*)malloc(strlen(skill) + 1);
if(this->skill == NULL)
return;
strcpy(this->skill,skill);
}
3.2 多继承
class 派生类:继承方式 基类名1,继承方式 基类名2
{
};
1)基类之间无关联
2)基类之间有关联(共同的基类)
如果继承关系存在菱形的继承关系,采用虚继承
class Sofa:virtual public Furniture
{
public:
void sit()
{
this->texture = 2;
cout << "--- sit" << endl;
}
};