C++满分密集
语法基础
引入头文件
1 |
使用命名空间
1 | using namespace std; //有分号“;” |
- 打印Hello World
- 使用命名空间:
cout<<"Hello World";
- 未使用命名空间:
std::cout<<"Hello World";
- 使用命名空间:
从键盘输入
1 | //定义要输入的变量,使用cin |
数组
像C一样定义数组
1 | int i[] = {1,2,3}; |
使用new关键字
1 | int *i = new int[10]; |
函数
主函数
1 | //返回值必须是int, 函数名别写成“面” |
函数重载
即使函数名相同,但参数等不同,就不是同一个函数
1 | //函数1 |
传参时,若将数组作为参数,形参写成指针
一般还会增加一个形参n,表示数组的长度,方便函数处理
1 | void test(int *p, int n){} |
类
class
英 / klɑːs /
n. (货物、服务或人的)等级,类别;
v. 把……归类,把……看作;属于……类(或等级),被列为某类(或某级)
1 | class Person{}; //注意有分号“;”,函数可写在分号后面 |
成员可见性
- public: 可在类外面直接访问
- private: 只能在类里面访问
- protected: private+可在子类中访问
1 | class Person{ |
定义成员函数
- 类内部
1
2
3
4
5class Person{
void test(){
cout<<"Hello World"<<endl;
}
}; - 类外部
1
2
3
4
5
6class Person{
void test(); //分号结尾
};
void Person::test(){
cout<<"Hello World"<<endl;
}
成员变量和函数的调用
……
对象
object
英 / ˈɒbdʒɪkt; əbˈdʒekt /
n. (引发某种情感或行为的)对象;物体,实物;目的,目标
构造函数
构造(创建)对象时,自动调用的函数
1 | class Person{ |
带参数的构造函数
1 | Person(int newAge, int newHeight){ |
等价
1 | //冒号分割,参数用逗号隔开,最后的花括号不要丢 |
通过带参数的构造函数创建对象
1 | int main(){ |
复制构造函数
与构造函数类似
1 | class Person{ |
析构函数
对象销毁时,程序自动调用的函数
1 | class Person{ |
静态成员
静态变量
使用static
关键字,将变量或函数标记为静态,静态成员属于类
,所有对象
共享
1 | class Person{ |
==不管如何访问count这个变量,count自始至终都是同一个==
静态函数
同样使用static
关键字
1 | class Person{ |
友元函数,友元类
友元函数
友元函数不属于类,直接通过函数名调用1
2
3
4
5
6
7
8
9
10
11
12class MyClass {
private:
int privateData;
public:
friend void friendFunction(MyClass &obj);
};
void friendFunction(MyClass &obj) {
// 可以访问 obj 的私有成员
obj.privateData = 10;
}友元类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27class Student{
//定义Teacher类为Student的友元类
friend class Teacher;
private:
int score;
public:
Student(int s):score(s){}
friend void setVal(Student &stu, int sco);
};
void setVal(Student &stu, int sco){
stu.score = sco;
}
class Teacher{
public:
static void showScore(const Student &s){
//此时,可以直接通过对象.属性访问private属性
cout<<s.score<<endl;
}
};
int main(){
Student s(90);
setVal(s,99);
Teacher::showScore(s);
}
继承
c++中,一个类可以继承自多个类
单继承
1 | class Person{ |
当通过Girl g
创建Girl对象时,首先会调用Girl的父类的构造函数,再调用Girl的构造函数
程序结束后,系统会自动调用析构函数销毁对象,子类会率先被销毁,最后销毁父类,因此,先调用Girl的析构函数,再调用Person的析构函数
当父类构造函数有参数时
1 | class Person{ |
子类的构造函数需要在初始化列表中调用父类的构造函数,并给一个参数,这样父类的构造函数才能正常执行
多继承
1 | class Person{ |
Person中的age和say()分别被继承了,Girlfriend有两个父类,此时Girlfriend类中有两个age和say(),直接通过gf.age
访问会报错,有两个age,鬼晓得你要访问哪个age,则通过gf.Girl::age
和gf.Friend::age
访问某一个age,注意:这两个age是两个不同的变量,值不同。
gf中的say()由于与Person中的say()相同,则直接覆盖了,使用gf.say()可以直接调用gf中的say(),并打印I love you!
为了解决二义性,可以只用virtual关键字,以虚基类的形式继承Personclass Girl:virtual public Person
class Friend:virtual public Person
此时gf.Girl::age
,gf.Friend::age
以及gf.age
是同一个变量
运算符重载
运算符重载,给运算符定义为我的功能,做到1+1=3
1 | class Person{ |
自增++
运算符
1 | class Person{ |
注意区分:
- 后置:
Person operator++(int)
后置在后面括号里写个int - 前置:
Person & operator++()
前置在前面加个&
虚函数
这玩意比较绕
多态:相同的代码,不同的功能
虚函数:
1 | class Person{ |
纯虚函数:
没有函数体,必须在子类中重写,否则报错virtual void virFunction()=0;
一般用在无需事例化的抽象类中
模版
对于不确定的参数类型,不用写一堆函数
对于函数,在函数上方加上template <typename T>
,接下来的函数中,使用T代指任意一种类型,可以是int,float等
要代指多种类型,则template <typename T1, typename T2>
1 | template <typename T> |
类模版,则在类定义前加上template <typename T>
1 | template <typename T> |