1. 拷贝构造函数
作用: 想像变量一样,用赋值的形式对类对象初始化
例如:
class person{
、、、、、、、、
};
person p2 = p1;
默认有拷贝构造函数,如果自己写,要求的参数格式为(以person类为例)
person(const person & x);//以应用的形式
拷贝构造函数也是构造函数的一种,所以没有返回值,以类名为函数名
如果自己写,就要在自己写的构造函数内, 完整的用初始化列表的形式,把变量都赋值一遍,不如不写;
而且,自己写了拷贝构造函数,也要自己写构造函数,把类内变量在自己写的构造函数内初始化一遍,不如不写。
视频学习参考什么是拷贝构造函数?_哔哩哔哩_bilibili
2. 重载(overload)
类内多个重名函数,但是参数列表不同,即便重名也不影响,灵活运用。
3. 多态
满足两个条件:(1)父类指针指向子类对象;(2)子类对虚函数重写;这种条件下父类指针调用虚函数,则是多态,理解为,同一件事,不同人干,结果不一样。
重写(override) 子类函数,函数名,返回值,参数列表,均与父类同名函数一致。
虚函数,父类内虚函数,virtual, 子类内只要与这个函数同名,无论加不加virtual,都是虚函数。
父类指针指向父类对象,调用虚函数,不存在虚实区别。
4. 类的多继承
一个类可以同时继承多个父类, 例如 class C: public A, public B
4.1 多个父类中有同名函数
// class 1
class A{
public:
void buy(){cout << "A" << endl;}
};
// class 2
class B{
public:
void buy(){cout << "B" << endl;}
};
// 派生类
class C: public A, public B{
public:
void buy(){cout << "C" << endl;}
};
class D: public A, public B{
public:
void cost(){cout << "D" << endl;}
};
int main(){
C c;
c,buy(); // 输出C,子类重写同名成员函数
D d;
d.buy(); // 输出报错,因为有两个父类里都有buy函数
d.A::buy(); // OK 加了作用域解析符,输出 A
d.B::buy(); // OK 加了作用域解析符,输出 B
return 0;
}
多个父类中有同名函数,需要添加作用域解析符
4.2 菱形继承
菱形继承(二义性, 成员冗余)
例如, 基类是A, B继承了A,C页继承了A, D又继承了B和C,那么相当于D间接继承了A两次,这就造成了成员冗余,
class BC0
{
public:
int K;
};
class BC1 : public BC0
{
public:
int x;
};
class BC2 : public BC0
{
public:
int x;
};
class DC : public BC1, public BC2{
};
int main( )
{
DC d;
d.x = 1; // error C2385: 对"x"的访问不明确
//可能是"x"(位于基"BC1"中),也可能是"x"(位于基"BC2"中)
d.BC1::x = 2; // OK,from BC1
d.BC2::x = 3; // OK,from BC2
d.K = 4; // error C2385: 对"K"的访问不明确
d.BC1::K = 5; // OK,from BC1
d.BC2::K = 6; // OK,from BC2
return 0;
}
此时类DC中有四个成员变量, 两个x 和两个K,造成了冗余,
解决方法: 加virtual关键字,实现虚拟继承
class A{}; class B: virtual A{}; class C: virtual A{};
class C : public B, public C{};
这样,就只会继承一遍A, 上述程序中d.K = 4; 就不会再报错了。
4.3 多继承下构造函数
子类对父类的继承,要在子类的构造函数中,先完成对父类的初始化,可以用初始化列表的形式
例如A是父类,B是子类,B的构造函数如果自己写的话,可以写成, B(): A(){},如果需要传递参数,可以写成,B(int n) : A (n){}
需要注意的是,在多继承情况下构造时,对基类的初始化,要先virtual,再非virtual,同等级别,就按照写的先后顺序,再是子类的成员初始化,最后是子类自己的构造函数。
详细参见C++ 多重继承-CSDN博客
5.纯虚函数
纯虚函数的声明如下: virtual void func() = 0;纯虚函数一定是没有定义的,函数定义要在派生类中实现,有纯虚函数的类为抽象类,是不可以实例化的。纯虚函数也是应用于多态。
6. 引用和指针的区别
引用本身并不创建新的变量,指针是创建了一个新的变量,指向对应变量的地址。
7.迭代器和指针
迭代器和指针具有一些类似的功能,都有->和++的操作符,假设现在一个数组不知道大小,指针容易越界,迭代器是从begin()到end(),不会越界。(个人理解)
8.C++编译过程
预编译——>编译——>汇编——>链接
9.导入C函数的关键字
extern “C”;
此外,C++可以重载函数,C不可以
10. new和malloc的区别
1.new是关键字,malloc是函数
2.new不成功会报错,malloc不成功返回null;
3.new返回具体类型指针,malloc需要强制类型转换。
11. 深拷贝与浅拷贝
浅拷贝: 新对象简单复制原对象;
深拷贝:对原对象的引用或指针指向的内容也复制;
这样做的目的是在修改新对象时不会影响原对象;
需要显式的定义拷贝构造函数来实现深拷贝。