以及菜鸟教程等资料来看,牵扯到的个人查的资料已放入代码段中
一、类和对象:
#include<iostream>
using namespace std;
class Date {
int year,month,day;
public:
/*Date(int y=0,int m=0,int d=0) {
year = y;
month = m;
day = d;
cout << "构造函数" << endl;
}*///方法一
Date() {
year = 0;
month = 0;
day = 0;
cout << "构造函数0" << endl;
//cin >> year >> month >> day;
}//方法二,重载构造函数
Date(int y, int m, int d) {
year = y;
month = m;
day = d;
cout << "Date构造函数" << endl;
}
Date(const Date& t) {
year = t.year;
month = t.month;
day = t.day;
cout << "拷贝构造函数" << endl;
}
~Date()
{
cout << "Date析构函数" << endl;
}
void show() const
{
cout << year <<" "<< month <<" " << day << endl;
}
};
class Person {
protected:
string name;
int age;
char gender;
Date date;//对象成员
const double pi;//常数据成员,往往初始化列表后来初始化值
static int count;//静态数据成员,该空间共享此数据的值
public:
//static int count;//静态数据成员,该空间共享此数据的值
Person(string n="", int a=0, char g='m', int y=0, int m=0, int d=0) :date(y, m, d), pi(3.14) {//先调用对象成员的构造函数
name = n;
age = a;
gender = g;
cout << "Person构造函数2" << endl;
count++;
}
~Person()
{
count--;
cout << "Person析构函数2" << endl;//析构顺序与构造相反
}
void show()const//const修饰变为常成员函数
{
cout << name << " " << age << " " << gender<<endl;
cout << pi << endl;
date.show();
cout << "Person个数:" << count << endl;
}
static void showcount()//静态成员函数,只能访问静态成员或者全局变量
{
cout << "count:" << count << endl;
}
friend ostream& operator<<(ostream& q, Person& p);//声明为友元,从而使重载操作符的函数中可以访问该类中的私有变量
};
ostream & operator<<(ostream& q, Person& p)
{
cout << p.name << " " << p.age << " " << p.gender << endl;
p.date.show();
}
int Person::count = 0;//静态数据成员的初始化
class Student :public Person//,Test//多继承在后面加基类
{
int grade, score;
public:
Student(string n = "", int a = 0, char g = 'm', int y = 0, int m = 0, int d = 0, int grade=1, int s=0) :Person(n, a, g, y, m, d)//缺省参数要写必须全写
{
this->grade = grade;
score = s;
cout << "Student的构造" << endl;
}
~Student()
{
cout << "Student的析构" << endl;
}
void show()
{
cout << name << endl;//基类里的权限和派生类的继承方式决定在派生类里的权限,(基类中私有则派生类不可访问)
Person::show();
cout << grade << " " << score << endl;
}
};
int main() {
//第4节
Person p1("wll", 19, 'w', 2002, 9, 10), p2;
//Student s("wll", 19, 'w', 2002, 9, 10, 2, 100);
//s.show();
//第三节
/*const Person p("ztx", 20, 'm', 2002, 4, 17);//const修饰变为常对象,常对象也只能调用常成员函数,例如如果上面的show函数不加const就会报错
Person p1("wll", 19, 'w', 2002, 9, 10), p2;
Person* p3 = new Person;
delete p3;
//cout << p2.count << endl;
//Person::showcount();//静态成员的访问,没有对象也能访问
/*Person p1("wll", 19, 'w', 2002, 9, 10);
cout << p1 << endl;*/
/*Date d(2022,6,8);*/
//第一节
//d.show();
//Date d1 = d;//拷贝了构造函数
//d1.show();
//Date d2;
//d2.show();
//d2 = d1;//等号赋值,不再拷贝构造函数
//d2.show();
//第二节
//Date* p;//指针不创建对象
//p = &d;
三种访问方法
//d.show();
//p->show();
//(*p).show();
//Date q[3] = { Date(1,1,1),Date(2,2,2),Date() };//创建对象数组
//q[0].show();
//q[2].show();//析构函数顺序与构造函数相反
//Date& w = d;//对象的引用(不创建对象)
//w.show();
//Date* qq = new Date(2002, 4, 17);//动态创建对象
//qq->show();
//delete qq;
return 0;
}
二、虚函数和多态:
#include<iostream>
using namespace std;
class Shape {
public:
//virtual void area() {//虚函数
// //cout << "No shape!" << endl;//如果不是虚函数则会输出这个
//}
virtual void area() = 0;//纯虚函数,有该函数的类称为抽象类,抽象类不可以直接创建对象
//virtual void fun() = 0;//后面的派生类都需要实现父类的纯虚函数才能创建对象,否则也是抽象类,不可以直接创建对象
virtual ~Shape()
{
//析构函数一般定义为虚函数(更好的释放空间),其派生类的析构函数也是虚函数
}
};
class Circle :public Shape {
int radius;
public:
Circle(int r) {
radius = r;
}
void area() {//派生类继承的函数也是虚函数
cout << "circle=" << 3.14 * radius * radius << endl;
}
};
class Rectangle :public Shape {
int width, height;
public:
Rectangle(int w, int h) {
width = w;
height = h;
}
void area() {
cout << "rectangle=" << width * height << endl;
}
};
//传指针
//void getArea(Shape* p) {
// p->area();
//}
//传引用地址
void getArea(Shape &p) {
p.area();
}
int main() {
Circle c(1);
Rectangle r(1, 2);
//Circle* q = new Shape;
Shape* q = new Circle(1);//赋值兼容性原则
getArea(*q);
//传指针
/*getArea(&c);
getArea(&r);*/
//传地址
getArea(c);
getArea(r);
//Shape s;//虚函数情况下可以创建
//s.area();
return 0;
}
三、虚继承:
#include<iostream>
using namespace std;
//虚继承
class A
{
public:
int a;
A(int a = 0) {
this->a = a;
cout << "构造A" << endl;
}
};
class B :virtual public A {
public:
int b;
B(int a = 2, int b = 1) :A(a)
{
this->b = b;
cout << "构造B" << endl;
}
};
class C :virtual public A {
public:
int c;
C(int a = 0, int c = 2) :A(a)
{
this->c = c;
cout << "构造C" << endl;
}
};
class D :public B, public C {
public:
D(int a, int b, int c) :A(a), B(a, b), C(a, c)
{
cout << "构造D" << endl;
}
void show() {
cout << a << b << c << endl;
}
};
int main() {
D d(1, 2, 3);
//cout << d.a << " " << d.b << " " << d.c << endl;
d.show();
return 0;
}
四、异常处理:
#include<iostream>
using namespace std;
/*内联函数inline
* 参考:
* https://www.runoob.com/cplusplus/cpp-inline-functions.html
一般都是1 - 5行的小函数。在使用内联函数时要留神:
1.在内联函数内不允许使用循环语句和开关语句;
2.内联函数的定义必须出现在内联函数第一次调用之前;
3.类结构中所在的类说明内部定义的函数是内联函数。*/
//异常,参考:
//https://www.runoob.com/cplusplus/cpp-exceptions-handling.html
//异常处理try...catch
/*double division(int a, int b)
{
if (b == 0)
{
throw "Division by zero condition!";
}
return (a / b);
}
int main()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}
catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}*/
//定义一个新的异常
struct MyException : public exception
{
const char* what() const throw ()
{
return "C++ Exception";
}
};
int main()
{
try
{
throw MyException();
}
catch (MyException& e)
{
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
}
catch (std::exception& e)
{
//其他的错误
}
}
五、运算符重载:
#include<iostream>
using namespace std;
//参考:
https://blog.csdn.net/u014583317/article/details/109217780
/*不能重载的运算符如下:
成员访问运算符.
域操作运算符::
空间计算运算符sizeof
条件运算符?:
成员指针运算符*
*/
/*
<<和>> 只能采用友员函数的方法重载
*/
/*
= 只能采用成员函数的方法重载
*/
//友员函数的方法比成员函数的方法多一个参数
class Student
{
string id;
int score;
public:
Student(string i="", int s=0)
{
id = i;
score = s;
}
bool operator>(const Student& s) {//通过成员函数的重载操作符>
if (score > s.score)
return true;
else
return false;
}
//运算符重载是类内重载时,运算符重载函数作为类的成员函数,以上述代码为例 a>b 相当于 a 对象调用>方法并且传入参数时 b 对象。
Student &operator++() {//前置++运算符,需要引用返回,不需要参数。返回自增后的值,且返回的是一个左值
/*返回“值”和返回“引用”是不同的
函数返回值时会产生一个临时变量作为函数返回值的副本,而返回引用时不会产生值的副本*/
//参考:
// https://blog.csdn.net/qq_33266987/article/details/53516977
//如果去掉&,则返回的是值,第二次++操作不会对s1操作,即结果为s1=101,s3=102
id = id;
score++;
return *this;//必须为左值或函数指示符
}
//Student operator++() {//方法2,但是只能单次操作,因为返回的是值
// id = id;
// score++;
// return Student(id, score);
//}
Student operator++(int) {//后置++,不需要引用返回,需要参数区分。返回自增前的值,且返回的是一个右值
Student temp = *this; //因为后置++,是先使用,后自++,所以这里要保存一个临时值,再++,返回的是临时值。
score++;
return temp;
}
Student& operator=(const Student& t) {//可能要连等,所以不能直接返回值,而是引用返回
cout << "=========" << endl;
id = t.id;
score = t.score;
return *this;
}
friend ostream& operator<<(ostream& q, const Student& s);//声明为友元,否则私有数据类型不可在类外访问
};
ostream& operator<<(ostream& q, const Student& s) {//重载操作符<<
//在重载<<时,返回值类型是ostream&, 第一个参数也是ostream& 。也就是说,表达式cout<<c的返回值仍是 cout,所以cout<<c<<endl;才能成立。
cout << s.id << " " << s.score<<endl;
return q;
}
int main() {
Student s1("ztx", 100), s2("xxx", 99);
cout << s1 << s2 << endl;//需要重载操作符<<才能直接输出Student类里的数据
if (s1 > s2)
//operator>(s1,s2) 通过友员重载
//s1.operator>(s2) 通过成员函数重载
{
cout << s1<<endl;
}
else {
cout << s2<<endl;
}
Student s3 = ++++s1;//需要重载操作符++
cout << s1 << s3 << endl;
Student s4 = s2++;
cout << s2 << s4 << endl;
Student s5 = s1;//会直接调用拷贝构造函数,不用重写
Student s6;//这里注意构造函数要有缺省参数
s6 = s1;//这里是operator=,但是一般不用重写,一般遇到与空间相关的才需要重写,比如写字符串类,注意重写时只能写在类的里面
cout << s5 << s6 << endl;
s6 = s5 = s2;
cout << s5 << s6 << endl;
return 0;
}
六、模板
#include<iostream>
#include <string>
using namespace std;
//参考:
//http://c.biancheng.net/view/320.html
//函数模板
/*
//template<class T>//模板函数,这个模板不能比较两个不同类型的
//T getMax(T a, T b)
//{
// if (a > b) {
// return a;
// }
// else
// {
// return b;
// }
//}
template<class T1,class T2>//模板函数,这个模板可以比较两个不同类型的,这里会把b转换成T1类型的
T1 getMax(T1 a, T2 b)
{
if (a > b) {
return a;
}
else
{
return (T1)b;
}
}
int main() {
int a = 3, b = 4;
cout <<"a?b="<< getMax(a, b) << endl;
double c = 6.66, pi = 3.14;
cout <<"c?pi="<< getMax(c, pi) << endl;
cout << "a?pi="<<getMax(a, pi) << endl;
return 0;
}*/
//类模板
template <class T1, class T2>
class Pair
{
public:
T1 key; //关键字
T2 value; //值
Pair(T1 k, T2 v) :key(k), value(v) { };//初始化列表
bool operator < (const Pair<T1, T2>& p) const;
};
template<class T1, class T2>//不能少
bool Pair<T1, T2>::operator < (const Pair<T1, T2>& p) const
//Pair的成员函数 operator <要通过实例化来变成模板类
{
return value < p.value;
}
int main()
{
Pair<string, int> student1("Tom", 19),student2("ztx",20); //实例化出一个类 Pair<string,int>
cout << student1.key << " " << student1.value << endl;
if (student1 < student2)
{
cout << student1.key << " " << student1.value << endl;
}
return 0;
}
七、文件读写:
#include<iostream>
#include<fstream>
using namespace std;
//参考:
//https://www.runoob.com/cplusplus/cpp-files-streams.html
int main() {
char data[100];
// 以写模式打开文件
ofstream outfile;
outfile.open("afile.dat");// , ios::out
cout << "Writing to the file" << endl;
cout << "Enter your name: ";
cin.getline(data, 100);
// 向文件写入用户输入的数据
outfile << data << endl;
cout << "Enter your age: ";
cin >> data;
cin.ignore();//跳过指定字符,我们可以用它舍弃掉缓冲区里的空格字符或者存在的换行符,参考:
//http://c.biancheng.net/view/280.html
//https://blog.csdn.net/qq_45129263/article/details/108519009
// 再次向文件写入用户输入的数据
outfile << data << endl;
// 关闭打开的文件
outfile.close();
// 以读模式打开文件
ifstream infile;
infile.open("afile.dat",ios::in);
if (!infile) {
cout << "infile is wrong!" << endl;
return 0;
}
cout << "Reading from the file" << endl;
//infile >> data;
在屏幕上写入数据
//cout << data << endl;
再次从文件读取数据,并显示它
//infile >> data;
//cout << data << endl;
while (!infile.eof()) {
infile.getline(data, sizeof(data));//一行行读取,getline参考:
//https://blog.csdn.net/weixin_44480968/article/details/104282535
//sizeof参考:
//https://www.cnblogs.com/huolong-blog/p/7587711.html
cout << data << endl;
}
// 关闭打开的文件
infile.close();
return 0;
}
注:本文仅供个人复习补天使用,出现的视频和文章参考均来自网络,侵删。