c++小结1

C++总结

构造函数以及基础

  • 关于三种构造函数
//下边的三个函数实现了函数重载
//类的带参构造函数(没有默认值) 只有它时会把无参构造覆盖
Coordinate(int x1, int y1){x=x1; y=y1;}
//带有一个默认参数的构造函数 必须从右到左赋给默认值 
Coordinate(int x1,int y1=5){}
//调用下边函数 会把2赋值给x1的位置
Coordinate p5(2);
//带有2个参数的默认值  这个函数相当于写了3个函数 无参构造,带有一个参的构造,带有2个参的构造
Coordinate(int x1=2,int y1=5){}  

//初始化成员列表 带有默认值这里不需要无参构造
A(int _a1=0,int _a2=0,int _a3=3):a1(_a1),a2(_a2),a3(_a3){		};

//类中的拷贝构造函数,不定义有默认的 参数为该类的有一个对象的引用 (当对象要做参数传入时一般传引用)
Coordinate(Coordinate &p){};
//创建一个该类对象
Coordinate p1(2,3);
//拷贝函数的调用 不会在调用普通构造函数
Coordinate p2(p1)
Coordinate p3=p2;

//析构函数,最后在用完对象,对象要消失时会执行,可以用于删除数据成员为指针的变量 delete name;(这里name被char *name定义过)
~Coordinate(){
    cout<<"Destructor is called."<<endl;
}
    
//类外写某类的成员函数(这里在类外定义拷贝构造函数) 前提是Coordinate(Coordinate &p);已经在类中声明
(返回值) 类名::方法名(){}
Coordinate::Coordinate(Coordinate &p){
	x=p.x;
	y=p.y; 
} 

//键盘录入信息时,定义输入函数直接输入信息到数据成员中,不要在方法中调用构造函数
void input(){
	cin>>name;
	cin>>num;
	cin>>chinese;
	cin>>math;
	cin>>english; 
} 
  • 使用指针创建对象以及调用方法,友元函数
//定义一个该类的指针,为它用new分配空间
Timer *pt=new Timer(12,59,59)
//指针对应的对象调用方法通过指针要使用箭头调用
pt->printUniversal();
pt->printStandard();
delete pt;

//友元函数
//一个全局函数在一个类中声明为friend 方法,则该全局函数称为该类的友元函数,此时该全局函数可以访问该类的私有成员
class location{
	private:
		double x,y;
	public:
		location(double _x=0,double _y=0):x(_x),y(_y){
		}
    	//友元函数
		friend double distance1(location &l1,location &l2);
};
double distance1(location &l1,location &l2){
	return sqrt(pow(l1.x-l2.x,2)+pow(l2.y-l1.y,2)) ;
}
  • 数组对象,指针变量做数据成员
#include<iostream>
#include<cstring>
using namespace std;
class Employee{
	private:
		long id;
		//这里只是定义了指针变量,其中*代表是指针类型的,name代表变量,所以方法中使用name即可,不使用*name 
		//但是没有分配空间,在构造函数中分配空间 
		char *name;
    //char name[20] 这样name就提前分配好了空间
		char *address;
		double salary;
	public:
		//构造函数 
		Employee(long _id,char *_name,char *_addr,double d){
			id=_id;
			salary=d;
			//给指针变量的数据成员分配空间根据内容大小  +1是因为还有/0结束符 
			name=new char[strlen(_name)+1]; 
			//把内容放到name指针变量指向的空间 
			strcpy(name,_name);
			address=new char[strlen(_addr)+1];
			strcpy(address,_addr); 
		}
		//析构函数
		~Employee(){
			delete name;
			delete address; 
		} 
		void set_id(long _id){
			id=_id; 
		} 
		void set_salary(double s){
			salary=s; 
		} 
		//这里加char是为了确保_name变量保存的内容不发生改变,只是用于赋值 
		void set_name(const char *_name){
			name=new char[strlen(_name)+1];
			strcpy(name,_name); 
		} 
		void set_address(const char *_addr){
			address=new char[strlen(_addr)+1];
			strcpy(address,_addr); 
		} 
		long get_id(){
			return id;
		} 
		double get_salary(){
			return salary;
		}
		char* get_name(){
			//这里返回的是name指针变量里边的内容 
			return name;
		}
		char* get_address(){
			return address;
		}
		void print(){
			//这里打印的是name指针变量里边的内容 
			cout<<"name:"<<name<<" id:"<<id <<" address:"<<address<<" salary:"<<salary<<endl; 
		}
};
int main(){
    //定义数组对象传参
	char name[20]="hj";
	char address[20]="";
	Employee e1(123,name,address,3000);
	cout<<e1.get_name()<<" "<<e1.get_id()<<" "<<e1.get_address()<<" "<<e1.get_salary()<<endl;
    
	e1.set_address("China");
	e1.set_id(2344);
	e1.set_salary(4000);
	e1.set_name("hys");
	e1.print(); 
} 

静态成员变量和方法

  • 静态成员变量初始化赋值在类外,定义静态成员变量在类里 ,静态成员方法定义可以在类里边

  • 静态成员函数只能访问静态成员变量或静态成员函数,不可访问非静态的普通成员函数、成员变量

#include<iostream>
#include<cstring>
using namespace std;
class Student{
	private:
		int score;
		//定义静态成员在修饰符后,返回值前加static修饰 
		static int total_score;
		static int count;
	public:
		Student(){
		} 
		Student(int s){
			score=s; 
		} 
		~Student(){
		}
		void account(int s){
			score=s;
			total_score+=s;
			count++;
		}
		void print(){
			cout<<"当前学生成绩"<<score<<endl;
		}	 
		//静态成员函数只能访问静态成员变量或静态成员函数,不可访问非静态的普通成员函数、成员变量
		static int sum(){
			return total_score;
		}
		static int average(){
			return total_score/count;
		}
		
}; 
//静态成员函数初始化在外边 定义静态成员数据使用static在类里
//静态成员变量一定要在类定义对象之前在类的外面进行初始化赋值,不能在类的里面,因为静态变量属于所有对象, 
 int Student::total_score=0;
 int Student::count=0;
int main(){
	//定义一个班的学生用数组 这里的每个stu是使用无参构造调用的,所以记得加无参构造方法 
	Student stu[5];
	//用于录入数据 
	int s; 
	for(int i=0;i<5;i++){
		cin>>s; 
		stu[i].account(s); 
		stu[i].print();
	} 
	//静态成员函数调用通过类名加::(双冒号)直接调用 
	cout<<"成绩之和:"<<Student::sum()<<" 平均分:"<< Student::average()<<endl;
	 
}
  • 关于魔方一道题
//定义4*4的魔方阵,是指该矩阵的各行值的和等于各列值的和,并等于两对角线值的和
#include<iostream>
using namespace std;
class magic{
	private:
		int first,step;
		int  m[4][4]; 
	public:
		//键盘录入初始值
		void getdata(int _f,int _s){
			first=_f;
			step=_s; 
		} 
	 	void setfirstmagic(){
	 		//将数据输入魔方 
	 		for(int i=0;i<4;i++){
	 			for(int j=0;j<4;j++){
	 				cout<<"m["<<i<<"]["<<j<<"]:"; 
	 				cin>>m[i][j]; 
				 } 
			 }
	
}
//生成最终魔方成员函数 这里返回值int为题中要求可以return 0
		int generate(){
			//用32减去初始魔方阵所有对角线(两条)上元素的值,然后将结果放在原来的位置
			int sum=m[0][0]+m[3][3];
			for(int i=0;i<4;i++){
				m[i][i]=sum-m[i][i];
				m[i][3-i]=sum- m[i][3-i];
			}
			return 0; 
		}
		//输出魔方 
		int  printmagic(){
			for(int i=0;i<4;i++){
	 			for(int j=0;j<4;j++){
	 				cout<<m[i][j]<<"\t"; 
				 } 
				 cout<<"\n"; 
			 }
			 return 0; 
		}
}
; 
int main(){
	magic m;
	m.getdata(1,2);
	m.setfirstmagic();
	m.generate();
	m.printmagic();
} 

派生

  • 点派生圆类
  • 在建立继承类的构造函数时,初始化被继承类的数据成员时用其构造函数
  • 继承后子类可以使用父类的public方法
#include<iostream>
#define PI 3.14159
using namespace std; 
class Point{
	private: 
		int x,y;
	public:
		Point(int a=0,int b=0){
			x=a;
			y=b;
		} 
		void ShowPoint(){
			cout<<"Point:("<<x<<","<<y<<")\n";
		}
		int Getx(){
			return x;
		}
		int Gety(){
			return y;
		}
		void setxy(int a,int b){
			x=a;
			y=b; 
		}
}; 
//定义圆类 公有继承点类 
class Circle:public Point{
		private:
			int r;
		public:
			//初始化时被继承类的数据成员初始化使用其构造函数 
			Circle(int x,int y,int ra):Point(x,y),r(ra){
			} 
			void setr(int ra){
				r=ra; 
			} 
			double Aera(){
				return PI*r*r; 
			} 
			void Move(int x_offset,int y_offset){
				int x1=Getx();
				int y1=Gety(); 
				x1+=  x_offset;
				y1+= y_offset;
				setxy(x1,y1); 
				
				//这里不能使用x/y,因为x/y在父类中为私有属性,将private修改为protected
				//数据成员的修饰符将取决于该类怎么继承父类,这里公有继承,当修改后可以使用x/y 
//				x=x+x_offset;
//				y=y+y_offset;
//				setxy(x,y); 
			} 
			void showCircle(){
				ShowPoint();
				cout<<"Radius:"<<r<<"\t";
				cout<<"Aera:"<<Aera()<<endl; 
			} 
			
}; 
int main(){
	Circle c(1,1,1);
	c.showCircle();
	c.Move(1,2);
	c.showCircle();
	//通过子类创建的对象可以直接访问父类方法 
	c.setxy(4,5);
	c.setr(2);
	c.showCircle(); 
} 
  • 派生类中方法重写的使用
		//重写输入教师资料方法 
		void getdata(){
            //表示调用其父类employer的getdata()方法
			employer::getdata();
			cout<<"输入工作时间"<<endl; 
			cin>>hour; 
		} 

运算符重载的方法

  • 单目运算符只有一个操作数

  • 双目运算符:两个操作数

  • 使用operator关键字

友元函数的自增(两种)

#include<iostream>
using namespace std;
class point {
	private:
		int x,y;
	public:
		point(int _x=0,int _y=0):x(_x),y(_y){
		} 
		//重载前置++ 返回一个点类 定义友元为了全局函数可以访问x,y私有成员变量 
		friend  point& operator++(point &p);
		//重载后置++ 返回一个点类  int是为了函数重载 
		friend  point operator++(point &p,int);
		void print(){
			cout<<"("<<x<<","<<y<<")"<<endl; 
		} 
};
//前置++ 先++后赋值  &表示返回加后的自己,而不会调用拷贝构造函数 
point& operator++(point &p){
	p.x++;
	p.y++;
	return p; 
}
//后置++ 先赋值后++ 
point operator++ (point &p,int){
	point t=p;
	p.x++;
	p.y++;
	return t; 
}
int main(){
	point p1(1,1);
	//后置++ 先赋值 后++ 
	point p2=p1++;
	p1.print();//(2,2)
	p2.print(); //(1,1) 
	//前置++ 先++ 后赋值
	point p3=++p2;
	p3.print();//(2,2)
	p2.print(); //(2,2)
	 
} 

成员函数的自增(两种)

#include<iostream>
using namespace std;
class Point{
	private:
		int x,y;
	public:
		Point(int _x=0,int _y=0):x(_x),y(_y){
		} 
		//前置++  
		Point& operator++();
		//后置++
		Point operator++(int); 
		void print(){
			cout<<"("<<x<<","<<y<<")"<<endl; 
		} 
}; 
//前置++ 
Point& Point::operator++(){
	x++;
	y++;
	return *this; 
} 
//后置++
Point Point::operator++(int){
	Point p=*this;
	x++;
	y++;
	return p;
} 
int main(){
	Point p1(1,2);
	//前置++
	Point p2=++p1;
	p1.print();//(2,3)
	p2.print(); //(2,3)
	//后置++
	Point p3=p2++;
	p3.print();//(2,3)
	p2.print();//(3,4) 
	 
}
  • .定义一个分数类,通过重载运算符实现分数的四则运算、求负运算和赋值运算。其中,要求加法“+” 和减法“-”用友元函数实现重载,其他运算符用成员函数实现重载。
#include<iostream>
using namespace std;
class FS{
	private:
		int fz,fm;
	public:
		FS(int _fz=0,int _fm=1):fz(_fz),fm(_fm){
		} 
		//友元实现+ -重载 这是双目运算符 
		friend FS operator+(const FS &fs1,const FS &fs2); 
		friend FS operator-(const FS &fs1,const FS &fs2); 
		//成员函数*和/ 
		FS operator*(const FS &fs); 
		FS operator/(const FS &fs); 
		//求负和赋值运算符 赋值运算符是双目运算符 ,取反为单目 
		 FS& operator-(); 
		 FS operator=(const FS &fs); 
		
		void print(){
			cout<<"计算所得分数为"<<fz<<"/"<<fm<<endl; 
		} 
}; 

//定义全局最小公倍数用于分母通分
int lcm(int m,int n){
	int m1=m,n1=n; 
	int t; 
	//比较大小把大的放前边
	if(m<n){
		t=m;
		m=n;
		n=t; 
	}
	//辗转相除找最大公约数
	while(m%n!=0){
		 	t=m%n;
		 	m=n; 
			n=t; 
		 }
	
	//求最小公倍数 =两数乘积/最大公约数 
	return m1*n1/n; 
} 


//定义一个全局+运算符重载函数 
FS operator+(const FS &fs1,const FS &fs2){
	FS fs; 
	//得到最小公倍数
	fs.fm=lcm(fs1.fm,fs2.fm);
	fs.fz=fs1.fz*fs.fm/fs1.fm+fs2.fz*fs.fm/fs2.fm; 
	return fs; 
}
FS operator-(const FS &fs1,const FS &fs2){
	FS fs; 
	//得到最小公倍数
	fs.fm=lcm(fs1.fm,fs2.fm);
	fs.fz=fs1.fz*fs.fm/fs1.fm-fs2.fz*fs.fm/fs2.fm; 
	return fs; 
}
FS FS::operator*(const FS &fs){
	FS rfs; 
	rfs.fz= this->fz*fs.fz;
	rfs.fm=fs.fm*this->fm;
	return rfs; 
} 
FS FS::operator/(const FS &fs){
	FS rfs;
	rfs.fz=this->fz*fs.fm;
	rfs.fm=this->fm*fs.fz;
	return rfs; 
} 
//该取反运算符把自己也改变了,返回自己所以加& 
FS& FS::operator-(){
	this->fz=-this->fz; 
	return *this; 
} 
FS FS::operator=(const FS &fs){
	if(this==&fs){
		return *this; 
	}
	this->fz=fs.fz;
	this->fm=fs.fm;
	return *this; 
} 
int main(){
	FS fs1(2,3);
	FS fs2(1,2); 
	//测试 + 
	FS fs3=fs2+fs1;
	fs3.print();//7/6
	
	//测试 -
	FS fs4=fs2-fs1;
	fs4.print();//-1/6 
	
	//测试 *法 
	FS fs5=fs1*fs2;
	fs5.print();//2/6 
	//测试 /法 
	FS fs6=fs1/fs2;
	fs6.print();//4/3
	 
	FS fs7=-fs1;
	fs7.print(); //-2/3
	fs1.print();//-2/3 
	
	fs6=fs2;
	fs6.print();//1/2 
} 

虚函数

  • 定义虚函数 基类函数被定为虚函数 ,则派生类中同名函数都是虚拟函数,不论继承多少层

  • 定义为抽象类 (含***有等于0的虚函数的类***即含有纯虚函数的类)

  • 虚函数有方法体,纯虚函数为0

  • 抽象类不能创建对象

  • 让基类指针指向派生类的对象 ,在基类的方法前用virtual修饰,可以在基类指针指向派生类对象时使用派生类的方法

#include<iostream>
using namespace std;
//该类定义为抽象类 (含有等于0的虚函数的类即含有纯虚函数的类)
class vehicle{
	//默认修饰符为private 	记得写 public 
	public:
		vehicle (){
			cout<<"vehicle constructor"<<endl; 
		}
		//非构造函数记得写返回值 
		//定义虚函数  基类函数被定为虚函数 ,则派生类中同名函数都是虚拟函数,不论继承多少层
		//纯虚函数 值为0 
		virtual	void run()=0;
		virtual void stop()=0;
		//虚函数  
		virtual	void run(){
			cout<<"run"<<endl; 
		}
}; 
class bicycle: virtual public vehicle {
	public:
		bicycle(){
			cout<<"bicycle constructor"<<endl; 
		} 
		void run(){
			cout<<"bicycle run"<<endl; 
		} 
		void stop(){
			cout<<"bicycle stop"<<endl; 
		} 
};
class motorear: virtual public vehicle{
	public: 
		motorear(){
			cout<<"motorear constructor"<<endl; 
		}
		void run(){
			cout<<"motorear run"<<endl; 
		} 
		void stop(){
			cout<<"motorear stop"<<endl; 
		} 
};
//写虚拟继承在这里没有什么作用 
class motorbicycle:  public bicycle, public motorear{
	public:
		 motorbicycle(){
		  	cout<<"motorbicycle constructor"<<endl; 
		 }
		 void run(){
			cout<<"motorbicycle run"<<endl; 
		} 
		void stop(){
			cout<<"motorbicycle stop"<<endl; 
		} 
}; 
int main(){
	// vehicle类为抽象类不能创建对象 
//	vehicle v;
//	v.run();
//	v.stop();
	
	bicycle b;
	b.run();
	b.stop();
	
	motorear mr;
	mr.run();
	mr.stop(); 
	 
	motorbicycle mb;
	mb.run();
	mb.stop(); 
	
	cout<<"-----------------------------"<<endl; 
	//定义vehicle指针 
	vehicle *ve;
//	让基类指针指向派生类的对象 ,在基类的方法前用virtual修饰,可以在基类指针指向派生类对象
//时使用派生类的方法 
	ve=&b;
	ve->run();
	ve->stop(); 
	
	ve=&mr;
	ve->run();
	ve->stop(); 
	 
	ve=&mb; 
	ve->run();
	ve->stop(); 
} 

抽象类

  • 基类函数被定为虚函数 ,则派生类中同名函数都是虚拟函数,不论继承多少层

    #include<iostream>
    #include<cmath>
    #define PI 3.14159 
    using namespace std;
    //定义抽象类 必须有纯虚函数 
    class Container{
    	public:
    		//抽象方法 这有纯虚函数在继承该抽象类的类中必须重写抽象方法 
    		virtual double aera()=0;
    		virtual double volume()=0;	
    }; 
    class Sphere: public Container{
    	private:
    		double radius;
    	public:
    		Sphere(double r=0):radius(r){
    		} 
    		double  aera(){
    			return  4*PI*pow(radius,2); 
    		} 
    		double volume(){
    			return  4/3*PI*pow(radius,3); 
    		} 
    }; 
    class Cylinder:public Container{
    	private:
    		double radius,height;
    	public:
    		Cylinder(double r=0,double h=0):radius(r),height(h){
    		} 
    		double aera(){
    			return PI*2*radius*(height+radius); 
    		} 
    		double volume(){
    			return PI*pow(radius,2)*height; 
    		} 
    }; 
    int main(){
    	Sphere s1(10);
    	cout<<"球表面积:"<<s1.aera()<<" 球体积:"<<s1.volume()<<endl;
    	Cylinder c1(10,10);
    	cout<<"圆柱表面积:"<<c1.aera()<<" 圆柱体积:"<<c1.volume()<<endl;
    
    } 
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值