c++笔记
第2周 ~ 第3周
内联成员函数
class A {
inline void funcA();
void funcB() {
}
}
void A::funcA() {
}
上面两个都是内敛成员函数
构造函数
如果没有定义构造函数,会提供一个默认构造函数。
class A {
}
A a1; //调用默认构造函数生成对象
A a2 = new A; //调用默认构造函数生成对象
class B {
int x;
public:
B(int _x){
x = _x;
}
}
B b1; //error
B b2 = new B; //error
B b3(2);
B b4 = new B(3);
例一:
class CSample {
int x;
public:
CSample() {
cout << "CSample 1 called" << endl;
}
CSample(int _x) {
x = _x
cout << "CSample 2 called" << endl;
}
}
int main() {
CSample arr1[2];
CSample arr2[2] = {1, 2};
CSample arr3[3] = {1};
CSample * parr4[2] = new CSample[2];
delete []parr4;
}
例二:
class Test {
Test(int x) {} // 1
Test(int x, int y) {} // 2
Test() {} // 3
}
Test arr1[3] = {1, Test(1, 2)} // 1, 2, 3
复制构造函数
X::X(X &) 或者 X::X(const X &)
如果未定义复制构造函数,编译器会默认生成一个
class A {
}
调用场景
1.
A a(b);
A a = b; // 初始化语句,而非赋值语句,如果是赋值语句,就不会调用复制构造函数了
- 函数参数为某个类对象时或者函数返回值,调用函数时,会调用参数类的复制构造函数
类型转换构造函数
怪怪的
复制语句中调用
析构函数
class Demo {
int id;
public:
Demo(int x) {
id = x;
cout << "Demo id=" << x << " Construct!" << endl;
}
~Demo() {
cout << "Demo id=" << id << " Destruct!" << endl;
}
}
int main() {
Demo demo(4);
demo = 6;
}
静态成员
封闭类
类包含成员对象时,构造函数需要用初始化列表。
初始化顺序与在类中的说明顺序一致。
友元
常量对象、常量成员函数、常引用
第4周
运算符重载
- 重载为普通函数
- 重载为成员函数
赋值运算符重载
只能重载为成员函数
与复制构造函数有什么区别呢
- 一个在初始化时用,一个在赋值时用
- 参数也不一样
深拷贝 & 浅拷贝
动态数组类
cout,cin运算符重载
第5周 继承和派生
protected访问权限
派生类的构造函数
先调用父类的构造函数,两种形式
- 隐式调用父类默认构造函数
- 列表形式调用父类构造函数
SON:SON(arg son-list):FATHER(arg father-list)
派生类的析构函数
先调用派生类的析构函数
public赋值兼容规则
第6周 多态和虚函数
基本概念
形式:函数前面加virtual关键字
表现:
- 派生类的指针可以赋值给基类指针
- 派生类对象可以赋值给基类引用
作用:可扩充性
- 在非构造函数、非析构函数中调用虚函数就是多态
- 派生类与基类中虚函数同名同参数表的函数,即使没有virtual也是虚函数
class Father {
public:
void func1() {func2();}
virtual void func2() {
cout << "father" << endl;
}
}
class Son : public Father {
public:
void func2() {
cout << "son" << endl;
}
}
int main() {
Son son;
Father* p = &son
p->func1(); // 输出啥
}
多态实现原理
包含虚函数的类(包括从父类继承来的虚函数)每个对象中都有虚函数表,pbase->Func()
这种调用形式,先在pbase指向的对象中找到虚函数表地址,然后在虚函数表中使用Func
查找其地址,最后执行函数。
虚析构函数
由多态引起的派生类对象析构函数未被调用问题,可以将基类析构函数定义为virtual
int main(){
Son son;
Father* p = &son;
delete p; //如果Father类的析构函数不定义为virtual,不会调用Son的析构函数。
}
纯虚函数 & 抽象类
纯虚函数: virtual void func1() = 0;
抽象类: 包含纯虚函数的就是抽象类
- 不能实例化,只能作为基类使用
- 抽象类的成员函数(非构造/析构函数)可以调用纯虚函数
第7周 文件 & 泛型
函数模板
template<class T1, class T2>
T2 print(T1 arg1, T2 arg2) {
cout << arg1 << " " << arg2 << endl;
return arg2;
}
有了泛型后,注意函数重载场景,函数匹配问题。
类模板
template<类型参数表>
class 类模板名
{
成员;
}
- 类模板与函数模板
- 类模板与非模板参数
- 类模板派生