西电软工大二下c++复习

 结合b站视频c++面向对象编程速成!90分钟搞定_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1oK4y1s7Jd/?spm_id_from=autoNext&vd_source=a393026ff275927090071e59dc379af0

 以及菜鸟教程等资料来看,牵扯到的个人查的资料已放入代码段中

 一、类和对象:

#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;
}

注:本文仅供个人复习补天使用,出现的视频和文章参考均来自网络,侵删。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值