C++总结

一、类与对象

1.const 常函数,常量

#include<stdio.h>

class A{
	public:
		A( int a = 50,int data=1):b(data){//初始化表
			this->a = a;
			printf("AAAAA\n");
			}
		
		~A(){
			printf("!~~~~~~~~~\n");
		}

		void show(void) const  //常亮函数 ,不会对成员进行修改
		{
			printf("b = %d\n",b);
			printf("a = %d\n",a);//证明常量函数可以打印非常量变量
            a++;              //因为是const函数,所以无法编译通过
		}
	private:
		int a;
		const int b;
};

int main(int argc, const char *argv[])
{
	A x(2);
	x.show();

	A y(3);
	y.show();

	A z;
	z.show();
	
	return 0;
}

2.static 注意区分 类与对象

vbnet 复制代码
#include<stdio.h>

class A{ //类
	public:
		static void func(void)//可以不依靠于对象而实现
		{
			printf("static \n");
		}
		static int data;
};

int A::data = 10;

int main(int argc, const char *argv[])
{
	A a;   //对象
	a.func(); //基于对象可以调用

   A::func(); //此为基于类的方式,若无static 则无法调用
	
   A x;     //对象
   x.data = 100;//基于对象的赋值
   A::data = 1000;//直接对类进行操作
   
	return 0;
}

二、普通运算符重载

vbnet 复制代码
#include<stdio.h>
#include<unistd.h>

class Timer{
	public:
		Timer()
		{
			hour = 0;
			min = 0;
			sec = 0;
		}
		~Timer()
		{
		}
		void addtimer(int sec = 1)
		{
			this->min +=(this->sec + sec)/60;
			this->sec = (this->sec + sec)%60;
		}
		void show()
		{
			printf("%2d:%2d:%2d\n",hour,min,sec);
		}


		Timer operator+(int sec)
		{
            Timer tem;
			tem.sec = this->sec + sec;  // t3 = t + 3     
			return tem;
		}

		Timer operator+(Timer &x)
		{
			Timer tem;                       //t2 = t + t1  tem代表的是t,参数中代表的是括号里面的参数
			tem.sec = sec + x.sec;
			tem.min = min + x.min;
			tem.hour = hour + x.hour;
			return tem;
		}

Timer operator++(int)   //后++
	{
		Timer tem = *this;//backup
	
		sec++;

		return tem;
	}

	Timer operator++()   //前++
	{
		sec++;
		return *this;
	}

	//若返回值是 对象,则无法被赋值
	//若返回值是引用(加上&),则可以被赋值
	
	int &operator[](int i)
	{
      switch(i)
	  {
        case 0:
			return hour;
        case 1:
			return min;
        case 2:
			return sec;

	  }
	}

	private:
		int hour;
		int min;
		int sec;
		};

int main(int argc, const char *argv[])
{
	Timer t;
	t.addtimer(3);

	Timer t1;
	t1.addtimer(5);

	Timer t2;
	t2 = t + t1;
	t2.show();
	/*
	printf("hour:%d\n",t2[0]);
	printf("min:%d\n",t2[1]);
	printf("sec:%d\n",t2[2]);

    t2[1] = 30;

	printf("hour:%d\n",t2[0]);
	printf("min:%d\n",t2[1]);
	printf("sec:%d\n",t2[2]);
*/

	Timer t3;
	t3 = t + 3;
	t3.show();

	/*
	Timer t;
	while(1)
	{
		t.addtimer(100);
		t.show();
		sleep(1);
	}
	*/
	return 0;
}

三、特殊运算符重载

3.1赋值运算符号

vbnet 复制代码
#include<stdio.h>
#include<string.h>

class A{
	public:
		A()
		{
			printf("A()\n");
			p = new char[10];
			strcpy(p,"hello");
		}
		A(const A &x)//拷贝构造函数
		{
			printf("const A &x\n");
			p = new char[10];
			strcpy(p,x.p);
		}

		A & operator = (A &x) //赋值运算符
		{
			printf("const A &x\n");
			p = new char[10];
			strcpy(p,x.p);
		}


		~A()
		{
			printf("~A()\n");
			delete []p;
		}
	
	private:
		char *p;
};



int main(int argc, const char *argv[])
{
	A x;
	A y = x;
	 
	y = x;

	return 0;
}

3.仿函数()

vbnet 复制代码
#include<iostream>

using namespace std;

class Converter{
	public:
		Converter(double rate)
		{
			this->rate = rate;
		}
	
		double operator()(double rmb)
		{
			return rmb*rate;
		}
	private:
		double rate;
};

int main(int argc, const char *argv[])
{
	Converter RMBtoUS(6.3);
	cout << RMBtoUS(10) << endl;
	cout << RMBtoUS(10) << endl;

	Converter RMBtoE(7.8);
	cout << RMBtoE(10) << endl;
	cout << RMBtoE(10) << endl;


	return 0;
}

四、组合与继承

4.1 组合

main.cpp

#include"arr.h"

class Stuma{
	public:
		Stuma(){
		}
		~Stuma(){}
		
		void savescore(int score)
		{
			scorearr.addtail(score);
		}

		void showscore(void)
		{
			scorearr.show();
		}
private:
		ARR scorearr; //在arr.c中已经实现了
		};

int main(int argc, const char *argv[])
{
	Stuma m;
	m.savescore(22);
	m.savescore(33);

	m.showscore();

return 0;
}

arr.cpp

#include"arr.h"
#include<stdio.h>
 void ARR::addtail(int data)
{
	this->data[tail++] = data;
}

 void ARR::show(void)
{
	int i = 0;
	for(;i<tail;i++)
		printf("%d",data[i]);
	printf("\n");
}

arr.h

#ifndef _ARR_
#define _ARR_
/*
typedef struct arr{
	int data[100];
	int tail;

	void (*addtail)(struct arr *arr,int data);
	void (*show)(struct arr *arr);
}ARR;

void init(struct arr *arr);
*/
class ARR{
	public:
		ARR():tail(0)//初始化表
	{
	}
		void addtail(int data);
		void show(void);
	private:
		int data[100];
		int tail;
};

#endif

4.2 继承

#include<iostream>

using namespace std;

class A{ //基类
	public:
		A(){}
		~A(){}
		void showx()
		{
			cout<<"xxxxxxxxx\n"<<endl;
		}
};
class AX:public A{   //  继承:派生类
	public:
		void showy()
		{
			cout<<"yyyyyyyyyyyy\n"<<endl;
		}
};
int main(int argc, const char *argv[])
{
	A a;
	a.showx();

	AX b;
	b.showx();
	b.showy();

	return 0;
}

五、多态

#include<stdio.h>

class A{
	public:
		A(){
		}
		~A(){}

		void show()  //若为 virtual void show();作用:派生类会覆盖基类同名的函数
		{
			cout<<"AAAAAAAAA\n"<<endl;
		}
};


class B:public A{
	public:
		void show()
		{
			cout<<"BBBBBBBBBB\n"<<endl;
		}
};

int main(int argc, const char *argv[])
{
	B b;
	B *q = &b;  //只认指针,不认对象
	A *p = &b; // 支持用基类的指针 指向派生类的地址
	
	return 0;
}

案例:计算各个周长的函数

#include<iostream>

using namespace std;
class shape{
	public:
		virtual double getC(void) = 0;
		//设为纯虚拟函数
	    //此基类主要是为了提供接口
	};
class cir:public shape{  //继承类
	public:
		cir(double ri):r(ri){}//构造函数直接赋值
			double getC(void)
		{
			return 2*3.14*r;
		}
	private:
		int r;
};
class tri:public shape{
	public:
		tri(double a,double b,double c):e1(a),e2(b),e3(c){}
		double getC(void)
		{
			return e1+e2+e3;
		}
	private:
		double e1;
		double e2;
		double e3;
};
class rec:public shape{
	public:
		rec(double e)
		{
			this->e = e;
		}
		double getC(void)
		{
			return 4*e;
		}
	private:
		double e;
};

double countC(shape *arr[],int n)
{
	double sum = 0;
	for(int i = 0;i<n;i++)
	{
		sum += arr[i]->getC();
	}
	return sum;
}
int main(int argc, const char *argv[])
{
	cir c(1);
	rec r(3);
	cir c1(2);
	tri t(3,3,3);
	shape *arr[] = {&c,&r,&c1,&t};
	cout<<"total c:"<<countC(arr,4)<<endl;

	return 0;
}

六、异常

vbnet 复制代码
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<exception>

using namespace std;

class argexception:public exception{
	public:
		const char* what() const throw()//不抛异常函数
		{
			return "arg Err !";
		}
};

int myatoi(const char *str)//后面没有throw表示什么异常都可以抛
{
	if(*str <'0' || *str > '9')
		throw argexception();
	else
		return atoi(str);
}

int main(int argc, const char *argv[])
{
	try{
		int data = myatoi("asfsa");
		cout << data << endl;
	}
	catch (argexception e)
	{
		cout << e.what() <<endl;
	}


	return 0;
}	

七、 转换函数

7.1 自定义转换

#include<stdio.h>
#include<unistd.h>
#include<iostream>

using namespace std;

class Timer{
	public:
		Timer()
		{
			hour = 0;
			min = 0;
			sec = 0;
		}
		~Timer()
		{
		}
		void addtimer(int sec = 1)
		{
			this->min +=(this->sec + sec)/60;
			this->sec = (this->sec + sec)%60;
		}
		operator int() //自定义强转类型符
		{
			return sec + min*60 + hour *60*60;
		}

	private:
		int hour;
		int min;
		int sec;
		};

int main(int argc, const char *argv[])
{
	Timer t;
	t.addtimer(3);
	int sec = t;
	cout << sec << endl;

	return 0;
}

7.2 隐式转换

#include<iostream>
using namespace std;

class mempool{
	public:
		explicit mempool(int size){
			data = new char[size];
			cout<<"this is 隐式转换"<<endl;
		}
		~mempool()
		{
			delete []data;
		}
	private:
		char *data;
};
int main(int argc, const char *argv[])
{
	mempool a(100);
	//mempool a = 100; //此语句也会调用构造函数,为了防止隐士转换,函数前加上expiicit

	return 0;
}

八、模版

#include<stdio.h>
#include<iostream>

using namespace std;

#if 0
int add(int a,int b)
{
	return a+b;
}
double add(double a,double b)
{
	return a+b;
}
#endif

template<typename xxx>
xxx add(xxx a,xxx b)
{
	return a+b;
}
int main(int argc, const char *argv[])
{
	cout<< add(1,2)<< endl;
	cout<< add(1.1,2.3) << endl;

	return 0;
}

九、STL算法

9.1、迭代器

#include <iostream>
#include <ostream>

using namespace std;

class myList{	
	struct Node{
		Node(int x, Node *ptr=NULL):data(x), next(ptr) { }
		int data;
		Node *next;
	};
public:
	class iterator{
	public:
		iterator(Node *ptr=NULL):pos(ptr) {  }
		iterator &operator++(int)
		{
			if(NULL != pos)
				pos = pos->next;
			return *this;
		}

		int &operator*()
		{
			return pos->data;
		}
	
		bool operator!=(iterator x)
		{
			return pos != x.pos;
		}
	private:
		Node *pos;
	};

public:
	myList():head(NULL) { }
	~myList() {
		while(head)
		{
			Node *tem = head;
			head = head->next;
			delete tem;
		}
	}

	void insert_head(int data)
	{
		Node *node = new Node(data);
		node->next = head;
		head = node;
	}
	
	iterator begin()
	{
		return iterator(head);
	}
	iterator end()
	{
		return iterator(NULL);
	}


	friend ostream &operator<<(ostream &out, const myList &list);

private:
	Node *head;
};

ostream &operator<<(ostream &out, const myList &list)
{
	myList::Node *tem = list.head;
	while(tem)
	{
		out<< tem->data <<',';
		tem = tem->next;
	}
	out << endl;

	return out;

}

int main()
{
	myList list;

	list.insert_head(1);
	list.insert_head(2);
	list.insert_head(4);
	list.insert_head(3);
	
	cout << list;
	
	myList::iterator i = list.begin();
	while(i != list.end() )
	{
		cout << *i <<endl;
		i++;
	}

}

链表功能的实现

#include<iostream>
#include<ostream>

using namespace std;

class myList{
	struct Node{//struct声明的默认为public
		Node(int x,Node *ptr = NULL):data(x),next(ptr){}
		int data;
		Node *next;
	};
	public:
	myList():head(NULL){}//链表的表头初始化为null
	~myList()
	{
		while(head)
		{
			Node *tem = head;
			head = head->next;
			delete tem;
		}
	}
	void insert_head(int data)
	{
		Node *node = new Node(data);//在堆中分配这个节点并赋值
		node->next = head;
		head = node;
	}
	friend ostream &operator<<(ostream &out,const myList &list);

	private:
	Node *head;
};
//  对 << (输出字符) 的运算符重载
ostream &operator<<(ostream &out,const myList &list)
{
	myList::Node *tem = list.head;
	while(tem)
	{
		out<<tem->data<<',';
		tem = tem->next;
	}
	out << endl;
	return out;
}
int main(int argc, const char *argv[])
{
	myList list;
	list.insert_head(1);
	list.insert_head(3);
	list.insert_head(2);
	list.insert_head(5);
	cout << list;

	return 0;
}

9.2、STL容器

例:迭代器和链表算法

#include<iostream>
#include<vector>
#include<list>

using namespace std;

int main(int argc, const char *argv[])
{
#if 0
      vector<int> arr;//迭代器的使用

	  arr.push_back(1);
	  arr.push_back(2);
	  arr.push_back(3);
	  arr.push_back(4);

#endif

	  //vector<double> arr;
	  list<double> arr;
	  arr.push_back(2.3);
	  arr.push_back(2.3);
	  arr.push_back(2.3);
	  arr.push_back(2.3);

	  //vector<int>::iterator i = arr.begin();
	  //vector<double>::iterator i = arr.begin();
	  list<double>::iterator i = arr.begin();//链表的使用
	  while(i != arr.end())
	  {
		  cout<< *i<<endl;
		  i++;
	  }
	return 0;
}

注意事项:

1.类中:若出现有参数的构造函数,则需要一个无参数的构造函数

2.新对象产生一定调用了构造函数

3.构造函数:a.无参数的 b.有参数的 c.拷贝构造函数

4.静态函数:基于类 而不是基于对象实现的方式

5.c++最好使用++i,少用i++

6.对象生成的时候才会调用构造函数

相关推荐
Re.不晚8 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
老秦包你会10 分钟前
Qt第三课 ----------容器类控件
开发语言·qt
凤枭香13 分钟前
Python OpenCV 傅里叶变换
开发语言·图像处理·python·opencv
ULTRA??17 分钟前
C加加中的结构化绑定(解包,折叠展开)
开发语言·c++
远望清一色33 分钟前
基于MATLAB的实现垃圾分类Matlab源码
开发语言·matlab
confiself43 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
凌云行者1 小时前
OpenGL入门005——使用Shader类管理着色器
c++·cmake·opengl
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
凌云行者1 小时前
OpenGL入门006——着色器在纹理混合中的应用
c++·cmake·opengl
杜杜的man1 小时前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang