根据实例复习Cpp
1. 还是这里开始Cpp
- #include <iostream>
- // 一个良好的编程习惯是将using直接跟在include之后
- using namespace std;
- int main()
- {
- int number1;
- int number2;
- int sum;
- cout << "Enter the first number :";
- cin >> number1;
- cout << "Enter the second number :";
- cin >> number2;
- sum = number1 + number2;
- // <<流操作符
- cout << "Sum is " << sum << endl;
- return 0;
- }
2. 定义第一个类
- // 定义第一个类
- #include <iostream>
- using namespace std;
- class GradeBook
- {
- public: // 访问修饰符
- // 定义类方法
- void displayMessage()
- {
- cout << "Welcome to GradeBook" << endl;
- }
- }; // 注意这里的分号
- int main()
- {
- // 声明GradeBook类,区分这里和c#中需要使用new关键字
- GradeBook g;
- g.displayMessage();
- return 0;
- }
3. 使用string对象
- // 使用string对象
- #include <iostream>
- #include <string>
- using namespace std;
- int main()
- {
- // 声明string对象str
- string str;
- // 读取一行
- getline(cin, str);
- // 输出
- cout << str;
- return 0;
- }
4. 类构造函数
- // 测试类的构造函数
- //
- // 如果一个类没有提供构造函数的话,编译器将生成一个默认的
- // 构造函数,在该构造函数中将调用类中每个数据程序的默认构造函数
- #include <iostream>
- using namespace std;
- class Student
- {
- public:
- Student()
- {
- cout << "Call Student default constructor\n";
- this->score = 0.0;
- }
- private:
- double score;
- };
- class GradeBook
- {
- public:
- int getData()
- {
- return data;
- }
- private:
- Student stu;
- int data;
- };
- int main()
- {
- // 在类GradeBook中没有构造函数,那么编译器将生成一个默认构造函数
- // 将调用Student的默认构造函数,但是data的值是不确定
- GradeBook g;
- cout << g.getData() << endl;
- return 0;
- }
5. Cpp中类定义和实现分文件
// Main.cpp
- #include <iostream>
- // 包含类定义头文件
- #include "GradeBook.h"
- int main()
- {
- GradeBook g;
- g.displayMsg();
- return 0;
- }
// GradeBook.h
- #ifndef _GRADE_BOOK_H_
- #define _GRADE_BOOK_H_
- // 仅仅是类定义
- class GradeBook
- {
- private:
- double data;
- public:
- void displayMsg();
- GradeBook();
- };
- #endif
// GradeBook.cpp
- #include <iostream>
- using std::cout;
- #include "GradeBook.h"
- // 类实现
- GradeBook::GradeBook()
- {
- this->data = 0.0;
- }
- void GradeBook::displayMsg()
- {
- cout << "Welcome to GradeBook !\n";
- }
6.else摇摆
- // 控制结构:else摇摆
- #include <iostream>
- using namespace std;
- int main()
- {
- int x = 3, y = 6;
- if (x > 5)
- if (y > 5)
- cout << "x and y are > 5" << endl;
- else // 这里的else匹配的是最近的那个if
- // 下面的程序将什么也不输出,因为x < 5
- cout << "x is <= 5";
- return 0;
- }
7. 存储类别,链接和作用域
这里有介绍,但是需要指明的是存储类别和作用域是相互独立的,不是说一个变量V在程序的整个运行期间都存在,并不代表在任何的作用域中该变量均能使用。
8.内联函数
- // 内联函数
- #include <iostream>
- using namespace std;
- // 使用管理之inline表明向编译器提出申请将这个
- // 函数内敛
- inline int max(int a, int b)
- {
- return (a > b) ? a : b;
- }
- int main()
- {
- return 0;
- }
9. cpp中的引用
- // cpp中的引用类型
- #include <iostream>
- using namespace std;
- // 在函数参数中使用引用
- void increase(int& a)
- {
- a++;
- }
- // 使用const表明的是在该函数中不改变a的值
- void print(const int& a)
- {
- // 将出现错误 a = 1;
- cout << a << endl;
- }
- int main()
- {
- int value = 0;
- // 声明引用,并赋值
- int& refValue = value;
- // refValue和value指向的是同一个对象,所以更改refValue的值将
- // 更改value的值
- refValue = 5;
- cout << "the value is :" << value << endl;
- int a = 0;
- // 注意这里的函数调用方式,这里和普通的函数调用是相类似的,
- // 但是却在函数内部改变了a的值
- increase(a);
- cout << "after Increase, a is "
- << a << endl;
- return 0;
- }
- // cpp默认实参
- #include <iostream>
- using namespace std;
- // 默认参数,语法的格式是直接在函数的形式参数中写入
- // 默认值
- int boxVolume(int length = 1,
- int width = 1,
- int height = 1)
- {
- return (length * width * height);
- }
- int main()
- {
- // 含有默认参数的函数的调用
- cout << "1, 1, 1 is " << boxVolume() << endl;
- cout << "1, 2, 1 is " << boxVolume(1, 2) << endl;
- cout << "1, 2, 3 is " << boxVolume(1, 2, 3) << endl;
- return 0;
- }
- // 一元作用域分辨运算符
- #include <iostream>
- using namespace std;
- // 全局变量
- int num = 10;
- int main()
- {
- // 局部变量
- int num = 5;
- cout << "local is " << num << endl;
- // 使用::来访问全局num变量
- cout << "global is " << ::num << endl;
- return 0;
- }
- // 函数重载
- #include <iostream>
- using namespace std;
- // 重载其他比较迷惑特性:默认参数重载,引用类型重载,const类型重载
- // 函数重载:c++在进行函数重载时只是根据函数的参数的
- // 类型来判断,不根据函数的返回值来区别两个函数,因为在
- // 编译器对重载函数进行编译时将根据参数的不同类型重新生成
- // 名字,同时忽略函数的返回值
- // #1
- void overloadFunc()
- {
- cout << "Call void overloadFunc()" << endl;
- }
- // #2
- void overloadFunc(int)
- {
- cout << "Call void overloadFunc(int)\n";
- }
- int main()
- {
- int a = 0;
- // #2
- overloadFunc(a);
- return 0;
- }
- // 函数模板
- #include <iostream>
- using namespace std;
- template <typename T>
- T maxValue(T a, T b)
- {
- return (a > b) ? a : b;
- }
- int main()
- {
- // 注意这里在使用时,不需要指明类型(max<int>)
- cout << maxValue(1, 2) << endl;
- cout << maxValue('a', 'b') << endl;
- // 这句将产生错误,两个参数的类型不一致
- // cout << maxValue('a', 10) << endl;
- return 0;
- }
- // 函数指针数组
- #include <iostream>
- using namespace std;
- void func1()
- {
- }
- void func2()
- {
- }
- void func3()
- {
- }
- int main()
- {
- // 声明函数指针数组
- void (*funcPtr[3])();
- funcPtr[0] = func1;
- funcPtr[1] = func2;
- funcPtr[2] = func3;
- return 0;
- }
全局变量的初始化是优先于main函数执行,然后开始执行main函数,在main函数中如果遇到自动变量对象,将调用该变量的构造函数,在该变量的作用域完成之后,将指定调用该变量的析构函数,如果是static变量的话,将在main函数结束之后调用析构函数。如果程序中遇到 exit或者是abort的话,将不调用任何对象的析构函数。
- // 函数指针数组
- #include <iostream>
- #include <string>
- using std::string;
- using std::cout;
- using std::endl;
- class CreateAndDestroy
- {
- public :
- CreateAndDestroy(int id, string msg)
- {
- m_objectId = id;
- m_message = msg;
- cout << "Object : " << m_objectId
- << " Constructor runs " << m_message << endl;
- }
- ~CreateAndDestroy()
- {
- cout << "Object : " << m_objectId
- << " Destructor runs " << m_message << endl;
- }
- private:
- int m_objectId;
- string m_message;
- };
- void create()
- {
- cout << "Create function : executuion begins" << endl;
- CreateAndDestroy fifth (5, "local automic in create");
- static CreateAndDestroy sixth (6, "local static in create");
- CreateAndDestroy seventh(7, "local automic in create");
- cout << "Create function : executuion ends" << endl;
- }
- // 全局变量
- CreateAndDestroy fist(1, "global before main");
- int main()
- {
- cout << "Main function execution begins" << endl;
- CreateAndDestroy second(2, "local automic in main");
- static CreateAndDestroy third(3, "local static in main");
- create();
- cout << "Main function : execution resumes " << endl;
- CreateAndDestroy fourth(4, "local automic in main");
- cout << "Main function : execution ends"<< endl;
- return 0;
- }
16. const对象和const成员函数
- // const成员函数
- #include <iostream>
- #include <string>
- using std::string;
- using std::cout;
- using std::endl;
- // 定义Time类
- class Time
- {
- private :
- int hour;
- int minute;
- int second;
- public:
- Time(int h = 0, int m = 0, int s = 0)
- {
- hour = h;
- minute = m;
- second = s;
- }
- // set方法
- // const函数,非const对象能够调用const函数,但是const
- // 对象只能调用 const成员函数
- void printTime() const
- {
- cout << "hour " << hour
- << " minute " << minute
- << " second " << second
- << endl;
- }
- };
- int main()
- {
- // 声明const对象
- const Time t(1, 1, 1);
- t.printTime();
- Time t2;
- t2.printTime();
- return 0;
- }
17. const产量初始化
- // const产量初始化
- #include <iostream>
- #include <string>
- using std::string;
- using std::cout;
- using std::endl;
- // 定义Time类
- class Time
- {
- private :
- const int CONSTANT;
- public:
- // const常量初始化语法,如果是const static产量的话,直接在定义处初始化
- Time() : CONSTANT(0)
- {
- }
- };
- int main()
- {
- Time t;
- return 0;
- }
18. 友元函数
- // 友元函数
- #include <iostream>
- #include <string>
- using std::string;
- using std::cout;
- using std::endl;
- // 定义Time类
- class Time
- {
- private :
- int hour;
- int minute;
- int second;
- public:
- Time(int h = 0 , int m = 0, int s = 0)
- {
- hour = h;
- minute = m;
- second = s;
- }
- // 定义friend函数。实际上友元函数可以在class的任何位置定义
- // 因为友元函数实际上不是该类的成员函数
- friend Time add(const Time& t1, const Time& t2);
- };
- // 定义有缘函数,这里不需要使用friend
- Time add(const Time& t1, const Time& t2)
- {
- return Time(t1.hour + t2.hour,
- t1.minute + t2.minute,
- t1.second + t2.second);
- }
- int main()
- {
- Time t1(1, 1, 1);
- Time t2(2, 2, 2);
- Time t3 = add(t1, t2);
- return 0;
- }
- // 类中的static成员和static函数
- #include <iostream>
- #include <string>
- using std::string;
- using std::cout;
- using std::endl;
- // 定义Time类
- class Time
- {
- private :
- int hour;
- int minute;
- int second;
- // 定义static成员变量
- static int instanceCounts;
- public:
- Time(int h = 0 , int m = 0, int s = 0)
- {
- hour = h;
- minute = m;
- second = s;
- // 使用类的静态变量
- Time::instanceCounts++;
- }
- // 定义static成员函数
- static int getInstanceCount()
- {
- return instanceCounts;
- }
- };
- // 虽然static成员默认已经进行了初始化为0,但是如果不添加这初始化的话
- // 在该文件中将找不到该变量
- int Time::instanceCounts = 0; // 文件作用域
- int main()
- {
- Time t1(1, 1, 1);
- Time t2(2, 2, 2);
- // 使用类的静态方法
- cout << "Time instance count is " << Time::getInstanceCount() << endl;
- // 调用类的static方法
- return 0;
- }
运算符重载仅仅是在简化客户端的程序的编程,可以直接调用运算函数:t1.operator==(t2);.
- // 运算符重载
- #include <iostream>
- #include <string>
- using std::string;
- using std::cout;
- using std::endl;
- // 定义Time类
- class Time
- {
- private :
- int hour;
- int minute;
- int second;
- public:
- Time(int h = 0, int m = 0, int s = 0)
- {
- hour = h;
- minute = m;
- second = s;
- }
- // 使用默认构造函数
- // 运算符重载==
- bool operator== (const Time& other)
- {
- return (hour == other.hour) &&
- (minute ==other.minute) &&
- (second == other.second);
- }
- // !=
- bool operator!= (const Time& other)
- {
- return !(*this == other);
- }
- // +
- Time operator+(const Time& other)
- {
- return Time(hour + other.hour,
- minute + other.minute,
- second + other.second);
- }
- // -
- Time operator-(const Time& other)
- {
- int hour = hour - other.hour;
- int minute = minute - other.minute;
- int sec = second - other.second;
- return Time(hour, second, sec);
- }
- // *
- Time operator*(int n)
- {
- return Time(hour * n,
- minute * n,
- second * n);
- }
- // 打印信息
- void printTime()
- {
- cout << "Hour : " << hour
- << " Minute : " << minute
- << " Second : " << second
- << endl;
- }
- };
- int main()
- {
- Time t1(1, 1, 1);
- Time t2(2, 2, 2);
- Time t3 = t1 + t2;
- t3.printTime();
- if (t1 == t2)
- cout << "t1 == t2" << endl;
- else
- cout << "t1 != t2" << endl;
- return 0;
- }
在c++中如果构造函数可以用作类型转换函数(如果想要禁止的话,可以使用关键字explicit禁止将该构造函数用作默认的类型转换函数),也可以指定以类的类型转换函数。
- // 类型转换函数,这里仅仅是为了演示,没有实际意义
- // 注意这里的函数格式,没有返回值
- operator int()
- {
- return 1;
- }
由于在c++中存在a++和++a的类型,所以编译器需要使用一个所谓的“哑元素”来区分是a++还是++a。
- // 定义++运算符
- // ++a形式
- Time& operator++ ()
- {
- second++;
- return (*this);
- }
- // a++形式
- Time operator++(int)
- {
- Time tmp = *this;
- second++;
- return tmp;
- }
23.类的继承属性
c++中存在三种类型的继承属性,如果不明确知名的话,默认的是private继承。不管是何种类型的继承,子类都是不能访问父类的private成员的,只是private,public,protected继承对于父类的public成员在子类中的行为是不相同的。同时需要注意的是:
1. 构造函数是不能够被继承的
2. 如果子类重写了父类的某个方法 ,但是还想调用覆盖的父类方法时,可以使用父类名::函数的形式调用
24 virtual关键字
- // 父类
- class BaseClass
- {
- public:
- BaseClass()
- {
- cout << "base class constructor. " << endl;
- }
- ~BaseClass()
- {
- cout << "baseclass destructor" << endl;
- }
- virtual void toOverrideFunc()
- {
- cout << "override function in baseclass." << endl;
- }
- };
- // 这里使用的是public继承
- class Subclass : public BaseClass
- {
- public:
- Subclass()
- {
- // 这里将首先调用BaseClass的构造函数
- cout << "subclass constructor. " << endl;
- }
- ~Subclass()
- {
- // 这里首先调用该类的析构函数,然后是父类的析构函数
- cout << "subclass destructor." << endl;
- }
- // 这里仅隐藏父类的该函数toOverrideFunc
- virtual void toOverrideFunc()
- {
- cout << "override function in subclass" << endl;
- }
- };
- int main()
- {
- // 没有使用virtual的话,那么函数调用将取决于调用的句柄
- // 如果使用了irtual的话,那么函数调用的将取决于实际的对象类型
- BaseClass* basePtr = new Subclass();
- // 这里将调用subclass中的函数
- basePtr->toOverrideFunc();
- Subclass* subPtr = new Subclass();
- subPtr->toOverrideFunc();
- delete basePtr;
- delete subPtr;
- return 0;
- }
c++中如果一个类想要成为抽象类的话,只需要将类中的一个成员函数声明为纯虚函数,纯虚函数是不能够有时显得,但是虚函数是能够有函数的时显的。
- // 纯虚函数
- #include <iostream>
- #include <string>
- using std::string;
- using std::cout;
- using std::endl;
- using std::ostream;
- using std::istream;
- using std::cin;
- // 父类,抽象类
- class BaseClass
- {
- public:
- // 纯虚函数
- virtual void pureVirtualFunc()= 0;
- };
- // 这里使用的是public继承
- class Subclass : public BaseClass
- {
- public:
- virtual void pureVirtualFunc()
- {
- cout << "in the subclass, we override the purevirtualFunc()"
- << endl;
- }
- };
- int main()
- {
- // 抽象类是无法实例化的
- // BaseClass b; // 错误
- BaseClass* basePtr = new Subclass();
- basePtr->pureVirtualFunc();
- delete basePtr;
- return 0;
- }
完结
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?