面向对象程序设计笔记

  • Post author:
  • Post category:其他


1.构造函数与析构函数

如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被

初始化为零

定义分成两部分,一是

静态变量的初始化

,二是

静态函数的定义

静态变量的初始化不能在类的定义中,但是可以在类的外部通过使用范围解析运算符

::

来重新声明静态变量从而对它进行初始化。而定义静态函数,那就与定义实例函数一样了。

静态成员的访问有以下两种方法:

  1. 使用

    类型名::静态成员

    格式访问;(可以将其看做是一个全局变量,只不过变量名要带上

    类型名::

    的前缀)

  2. 通过对象访问;(可以将其看做是对象中的一个实例成员)

cout << Test::HelloStr << endl;     // 通过作用域运算符访问  
Test::HelloStr = "World";     // 修改静态变量 HelloStr  
Test t1;  
cout << t1.HelloStr <<endl;     // 通过对象访问  
Test::Hello();     // 通过作用域运算符访问  
t1.World();     // 通过对象访问  

class User{
	public:
		string Name;
		int Books=0;
		static int tot_books,tot_ren;
		User(string name,int books):Name(name),Books(books){
			cout<<Name<<" "<<Books<<" 进入"<<endl;
			tot_books+=Books;
			tot_ren++;
		};
		~User(){
			cout<<Name<<" "<<Books<<" 离开"<<endl;
			tot_books-=Books;
			tot_ren--;
		};
		static void GetState(){
			cout<<"书店人数:"<<tot_ren<<",书店共享书数量:"<<tot_books<<",人均共享数量:"
			<<tot_books/tot_ren<<endl;
		}
};
int User::tot_books=0;
int User::tot_ren=0;

2.内部类练习

注意:牛腿的长度默认为牛高的一半

#include<string>
#include<iostream>
using namespace std;
class Cow{
    public:
        int weight,height;
        Cow(int _weight,int _height):weight(_weight),height(_height){};
        class CowLeg{
            public:
                string color;
                int length;
                CowLeg(string _color,int _length):color(_color),length(_length){};
                void show(){
                    cout<<"牛腿的颜色是"<<color<<endl;
                    cout<<"牛腿的长度是"<<length<<endl;
                }
        };
        void display(string _color){
            CowLeg leg(_color,height/2);
            leg.color=_color;
            leg.show();
            cout<<"整牛高"<<height<<endl;
            cout<<"整牛重"<<weight<<endl;
        }
};

3.类的书写(运算符重载)

3.1复数

class Complex{
	public:
		double real,image;
		Complex(double r,double i):real(r),image(i){};
		void Print(){
			if(image>=0) cout<<real<<"+"<<image<<"i"<<endl;
			else cout<<real<<image<<"i"<<endl;
		}
		Complex operator + (const Complex tem){
			return (Complex){real+tem.real, image+tem.image};
		} 
		Complex operator - (const Complex tem){
			return (Complex){real-tem.real, image-tem.image};
		} 
		Complex operator * (const Complex tem){
			//(a+bi)(c+di)=(ac-bd)+(ad+bc)i;
			return (Complex){real*tem.real-image*tem.image, real*tem.image+tem.real*image};
		} 
        Complex operator / (const Complex tem){
            double a=real,b=image,c=tem.real,d=tem.image;
			//(a+bi)(c-di)/(c^2+d^2)=[(ac+bd)+(bc-ad)i]/(c^2+d^2);
			return (Complex){(a*c+b*d)/(c*c+d*d),(b*c-a*d)/(c*c+d*d)};
		} 
};

强制类型转换调用

int a;
Int b=(Int)a;

3.2<<与>>重载

<< 和 >> 的重载一般使用 friend


class 1 Time

#include<iostream>
using namespace std;
class Time{
	private:
		int hour,minute,second;
	public:
		Time():hour(0),minute(0),second(0){};
		Time(int h,int m,int s):hour(h),minute(m),second(s){};
		Time operator +(const Time& b){
			Time t1;
			t1.hour=hour+b.hour;
			t1.minute=minute+b.minute;
			t1.second=second+b.second;
			if(t1.second>=60)t1.second-=60,t1.minute++;
			if(t1.minute>=60)t1.minute-=60,t1.hour++;
			if(t1.hour>=24)t1.hour-=24;
			return t1;
		}
		friend ostream& operator<< (ostream& os,const Time & b);
		friend istream& operator>> (istream& is,Time & b);
};
ostream& operator << (ostream& os,const Time& b){
	os<<b.hour<<':'<<b.minute<<':'<<b.second<<endl;
	return os;
};
istream& operator >> (istream& is,Time& b){
	is>>b.hour>>b.minute>>b.second;
	return is;
};


class 2 Point

测试主函数

int main(){
	int a,b;
    cout<<"输入第一个点:"<<endl;
    cin>>a>>b;
    Point p1(a,b);
    cout<<"输入第二个点:"<<endl;
    cin>>a>>b;
    Point p2(a,b);
    double d=p1-p2;   
    cout<<p1<<"->"<<p2<<"="<<d<<endl;  
    return 0;
}

要求实现输出

输入第一个点:

输入第二个点:

[2,4]->[7,-1]=7.07107


答案

#include<bits/stdc++.h>
using namespace std;
class Point{
    public:
        int x,y;
        Point(){};
        Point(int _x,int _y):x(_x),y(_y){};
        double operator -(const Point& p){
            return sqrt(pow(x-p.x,2)+pow(y-p.y,2));
        };
        friend ostream& operator << (ostream&,Point);
};
ostream& operator << (ostream& os,Point p){
    return os<<'['<<p.x<<','<<p.y<<']';
};

3.3分数类(fraction)

gcd 求最大公因数

#include<bits/stdc++.h>
using namespace std;
int gcd(int p,int q){
    return !q ? p : gcd(q,p%q);
}
class fraction{
    public:
        int mol,den;// molecule denominator
        //构造函数
        fraction(const fraction & f2){ mol=f2.mol,den=f2.den; };
        fraction(int p,int q){
            if(q==0) cout<<"error"<<endl;
            else {
                int maxn=gcd(p,q);
                p/=maxn;  q/=maxn;
                if(q<0){q=(-q),p=(-p);};
            }
            mol=p,den=q;
        };
        fraction():mol(1),den(1){};
        
        fraction operator +(const fraction &f2){
            // a/b + c/d=(ad+bc)/bd
            int a=mol,b=den,c=f2.mol,d=f2.den;
            int a1=a*d+b*c,b1=b*d;
            fraction ans(a1,b1);
            return ans;
        };

        fraction operator -(const fraction &f2){
            // a/b - c/d=(ad-bc)/bd
            int a=mol,b=den,c=f2.mol,d=f2.den;
            int a1=a*d-b*c,b1=b*d;
            fraction ans(a1,b1);
            return ans;
        };

        fraction operator *(const fraction &f2){
            // a/b * c/d=ac/bd
            int a=mol,b=den,c=f2.mol,d=f2.den;
            int a1=a*c,b1=b*d;
            fraction ans(a1,b1);
            return ans;
        };

        fraction operator /(const fraction &f2){
            // a/b / c/d=ad/bc
            int a=mol,b=den,c=f2.mol,d=f2.den;
            int a1=a*d,b1=b*c;
            fraction ans(a1,b1);
            return ans;
        };

        bool operator ==(const fraction &f2){
            if(mol==f2.mol && den==f2.den)return true;
            return false;
        };

        friend istream& operator >>(istream& is,fraction & f1);
        friend ostream& operator <<(istream& os,const fraction & f1);
};

istream& operator >>(istream& is,fraction & f1){
    return is>>f1.mol>>f1.den;
}
ostream& operator <<(ostream& os,const fraction & f1){
    if(f1.den==1) return os<<f1.mol;
    return os<<f1.mol<<"/"<<f1.den;
}

int main(){
    fraction f1,f2;
    cout<<"请输入第一个分数:"<<endl;
    cin>>f1;
    cout<<"请输入第二个分数:"<<endl;
    cin>>f2;
    cout<<"加法结果:"<<endl;  cout<<f1+f2<<endl;
    cout<<"减法结果:"<<endl;  cout<<f1-f2<<endl;
    cout<<"乘法结果:"<<endl;  cout<<f1*f2<<endl;
    cout<<"除法结果:"<<endl;  cout<<f1/f2<<endl;
    if(f1==f2)cout<<"两个分数相等!"<<endl;
    else cout<<"两个分数不相等!"<<endl;
    return 0;
}

3.4 Intset

测试主函数

int main(){   
	IntSet A;  A.add(3);  A.add(5);  A.add(1);

	cout<<"Set A"<<endl;
	A.show();  A.del(0);

	cout<<"Set A-"<<endl;  A.show();
	IntSet B;  B.add(5);  B.add(4);

	cout<<"Set B"<<endl;  B.show();
    
    cout<<"Set A+B"<<endl;  (A+B).show();   //并  
	cout<<"Set A-B"<<endl;  (A-B).show();   //差
	cout<<"Set A*B"<<endl;  (A*B).show();   //交

	IntSet C=A;  cout<<"Set C"<<endl;  C.show();
	A-=B;  A.show();  //实现-=
}

实现如下输出

Set A

show all node in the link:

1) 3

2) 5

3) 1

the number to be delted is not in the set!Set A-

show all node in the link:

1) 3

2) 5

3) 1

Set B

show all node in the link:

1) 5

2) 4

Set A+B

The num is in the set!

show all node in the link:

1) 5

2) 4

3) 3

4) 1

Set A-B

Delete 5!

show all node in the link:

1) 3

2) 1

Set A*B

Delete 3!

Delete 1!

show all node in the link:

1) 5

Set C

show all node in the link:

1) 3

2) 5

3) 1

Delete 5!

show all node in the link:

1) 3

2) 1

#include<bits/stdc++.h>
using namespace std;
class IntSet{
    public:
        vector<int> ar;
        IntSet(){};
        IntSet(const IntSet& a){ar=a.ar;};
        void add(int a){ ar.push_back(a); };
        void show(){
            cout<<"show all node in the link:"<<endl;
            for(int i=0;i<ar.size();i++)
                cout<<i+1<<") "<<ar[i]<<endl;
        }
        void del(int a){
            if(find(ar.begin(),ar.end(),a)!=ar.end()){
                ar.erase(find(ar.begin(),ar.end(),a));
            }
            else cout<<"the number to be delted is not in the set!";
        }
};
IntSet operator +(const IntSet& a,const IntSet& b){
    bool check=0;
    for(int i=0;i<a.ar.size();i++)
        for(int j=0;j<b.ar.size();j++)
            if(a.ar[i]==b.ar[j])check=1;
    if(check)cout<<"The num is in the set!"<<endl;

    IntSet ans(b);
    for(int i=0;i<a.ar.size();i++)
        if(find(b.ar.begin(),b.ar.end(),a.ar[i])==b.ar.end())
            ans.ar.push_back(a.ar[i]);
    return  ans;
};
IntSet operator -(const IntSet& a,const IntSet& b){
    IntSet ans(a);
    for(int i=0;i<b.ar.size();i++)
        if(find(ans.ar.begin(),ans.ar.end(),b.ar[i])!=ans.ar.end()){
            ans.ar.erase(find(ans.ar.begin(),ans.ar.end(),b.ar[i]));
            cout<<"Delete "<<b.ar[i]<<"!"<<endl;
        }
    return  ans;
};
IntSet operator *(const IntSet& a,const IntSet& b){
    IntSet ans(a);
    for(int i=0;i<a.ar.size();i++)
        if(find(b.ar.begin(),b.ar.end(),a.ar[i])==b.ar.end()){
            cout<<"Delete "<<a.ar[i]<<"!"<<endl;
            ans.ar.erase(find(ans.ar.begin(),ans.ar.end(),a.ar[i]));
        }
    return  ans;
};
void operator -=(IntSet& a,const IntSet& b){
    IntSet ans(a);
    for(int i=0;i<a.ar.size();i++)
        if(find(b.ar.begin(),b.ar.end(),a.ar[i])!=b.ar.end()){
            cout<<"Delete "<<a.ar[i]<<"!"<<endl;
            ans.ar.erase(find(ans.ar.begin(),ans.ar.end(),a.ar[i]));
        }
    a=ans;
};


3.5 Date (++运算符的重载)

测试主函数

int main(){
    int year1,year2,month1,month2,day1,day2;
    cin>>year1>>month1>>day1;
    cin>>year2>>month2>>day2;
	Date d1(year1,month1,day1);
	Date d2(year2,month2,day2);
	cout<<(d1-d2)<<endl;
	Date d4=d1+5;   d4.show();
    Date d5=10+d2;  d5.show();
	Date d6=d1++;   d6.show();
	Date d7=++d1;   d7.show();
	Date d8=++++d1; d8.show();
}

要求实现的输出

13038

2021/1/5

1985/5/1

2020/12/31

2021/1/2

2021/1/4


answer

const int run_mon[]={0,31,29,31,30,31,30,31,31,30,31,30,31};
const int mon[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
inline bool run(int year){
    if(year%4==0 &&(year%100!=0  || year%400==0)) return true;
    return false;
}
class Date{
    public:
        int ymd;
        Date(){};
        Date(const Date& temp){ymd=temp.ymd;};
        Date(int _y,int _m,int _d){ymd=_y*10000+_m*100+_d;};
        Date(int _ymd){ymd=_ymd;};
        Date operator + (int inc){//increase
            int y=ymd/10000, m=ymd/100%100, d=ymd%100;
            while(inc--){
                ++d;
                if(run(y)){
                    if(d>run_mon[m]){d=1; m++;};
                    if(m>12){m=1,y++;};
                }
                else {
                    if(d>mon[m]){d=1; m++;};
                    if(m>12){m=1, y++;};
                }
            }
            return (Date) (y*10000+m*100+d);
        }
        Date operator ++ (int){//后置++
            Date temp=*this;
            *this=*this+1;
            return temp;
        }
        Date operator ++ (){//前置++
            *this=*this+1;
            return *this;
        }
        void show(){ cout<<ymd/10000<<'/'<<ymd/100%100<<'/'<<ymd%100<<endl; }
};
Date operator + (int inc,Date d1){ return d1+inc; }
int operator - (Date temp1,Date temp2){
    int cnt=0;
    if(temp1.ymd>temp2.ymd){
        while(temp1.ymd!=temp2.ymd)cnt++,temp2++;
    }
    else{
        while(temp2.ymd!=temp1.ymd)cnt--,temp1++;
    }
    return cnt;
}

3.6 String


class 1

#include <bits/stdc++.h>
using namespace std;
class String {
	char *str1,*str2,*str;
	String str(char *s1,char *s2){
		char *p=str;
		while(*s1!='\0')*p=s1++;
		while(*s2!='\0')*str=s2++;
		*str='\0';
	}
	void dele(){
		char *p1=str,*p2=str;
		while(*p1!='\0'){
			if(*p1!=' '){*p2=*p1;  p2++; }
			p1++;
		}
	}
	void sort{
		char *l=str,*r=str;
		while(*r!='\0'){r++};r--;
		for(char *i=l;*i!=r-1;i++)
		for(char *j=i+1;*j!=r;j++)
			if(*i>*j){ char temp;  temp=*i;  *i=*j;  *j=temp; }
	}
	void show{
		char *p=str;
		while(*p!='\0'){cout<<*p;  p++; }
	}
}


class 2

测试主函数

int main(){
	String str1;
	str1.set("I love ");
	String str2("you");
	String str3 = str1+str2;
	str3.show();
	String str4=str1+"love ";
	str4.show();
	if(str3<str2) cout<<"str3<str2"<<endl;
	else if(str3==str2) cout<<"str3==str2"<<endl;
	else cout<<"str3>str2"<<endl;
	str1[1] = str2[1];
	str1.show();
	str2.show();
}

要求实现输出

I love you

I love love

str3<str2

Iolove

you


answer

#include <bits/stdc++.h>
using namespace std;
class String {
    public:
        string s;
        String(){};
        String(string _s):s(_s){};
        void set(string _s){ s=_s; };
        void show(){cout<<s<<endl;}
        // 注意这里的char& 如果写成char则不行
        char& operator [](int index){ return s[index]; }
};
String operator +(String tem1,String tem2){ return (String)(tem1.s+tem2.s); };
String operator +(String tem1,string _s){ return (String)(tem1.s+_s); };
bool operator <(String tem1,String tem2){ return tem1.s<tem2.s; };
bool operator ==(String tem1,String tem2){ return tem1.s==tem2.s; };

4.友元函数与友元类

4.1友元函数

有时候我们希望某个函数能访问一个类的非公有成员,但又不想把它做成这个类的成员函数,这个时候就可以使用友元。

如果要将一个函数变成一个类的友元,只需要在类中函数前加一个 friend 关键字来声明函数即可,并且访问性不受限制。即表现形式为:

friend <返回类型> <函数名> (<参数列表>);  

但这个友元函数他不属于该类的成员函数,他是定义在类外的普通函数,只是在类中声明该函数可以直接访问类中的 private 或者 protected 成员。

class Test{  
    private:  
        int a;  
    protected:  
        int b;  
    public:  
        friend void fun(Test t);// 友元函数  
};
void fun(Test t){  
    t.a=100;  
    t.b=2000;  
    cout<<"a = "<<t.a<<", b = "<<t.b<<endl;  
}
int main(){  
    Test test;  
    fun(test);  
    return 0;  
}  

4.2友元类

C++ 中也允许声明一个类为某个类的友元类,方法和声明友元函数旗鼓相当。但是需要注意的是,作为友元的类的声明必须在友元类的声明之前。

class TestFriend{  
    private:  
        int a;  
};// TestFriend 类的声明在 Test 类之前
class Test{  
    private:  
        int a;  
        friend class TestFriend;     // 声明友元类  
};  

有时候作为友元的类的声明不便放在友元声明之前,这个时候就可以使用

前置声明

。不过前置声明的类只是一个名字(或者说不完全类型),不能访问它内部的内容。

class TestFriend;// 前置声明 TestFriend 类,只是一个名字
class Test{  
    private:  
        int a;  
        friend class TestFriend;     // 声明友元类
        // 尝试将 TestFriend 类的成员函数 Func 作为友元函数,
        但由于 TestFriend 类目前只有前置声明,所以会出错。  
        friend void TestFriend::Func();     
};
class TestFriend{//TestFriend 类的声明在 Test 类之后  
    private:  
        int a;  
    public:  
        void Func();  
};  

由于类型转换时需要访问a种private的变量,所以要在a中将b声明为友元类

#include <iostream>
#include <string>
using namespace std;
class Teacher;
class Student{
	private:
		int number;
		string name,sex;
	public:
		Student(int num,string nam,string se):number(num),name(nam),sex(se){};
		void Print(){
			cout<<"学生:"<<name<<",编号:"<<number<<",性别:"<<sex<<endl;
		}	
		friend class Teacher;
};

class Teacher{
	private:
		int number;
		string name,sex;
	public:
		void Print(){
			cout<<"教师:"<<name<<",编号:"<<number<<",性别:"<<sex<<endl;
		}
		Teacher(const Student &a):number(a.number),name(a.name),sex(a.sex){};
};

4.3应用(矩阵)

#include<bits/stdc++.h>
using namespace std;
class Matrix{  
    public:
        int a[100][100];
        int r,c;
        Matrix(int _r,int _c):r(_r),c(_c){};
        void Fill(int value){
            for(int i=0;i<r;i++)
                for(int j=0;j<c;j++)
                    a[i][j]=value;
        }
        void Set(int r,int c,int value){ a[r][c]=value; }
        int Get(int r,int c){ return a[r][c]; }
        void Print(){
            for(int i=0;i<r;i++)
                for(int j=0;j<c;j++)
                    cout<<a[i][j]<<" ";
            cout<<endl;
        }
};

Matrix operator + (Matrix &m1,Matrix &m2){
    Matrix ans(m1.r,m1.c);
    ans.Fill(0);
    for(int i=0;i<m1.r;i++)
        for(int j=0;j<m1.c;j++)
            ans.a[i][j]=m1.a[i][j]+m2.a[i][j];
    return ans;
}

Matrix operator - (Matrix &m1,Matrix &m2){
    Matrix ans(m1.r,m1.c);
    ans.Fill(0);
    for(int i=0;i<m1.r;i++)
        for(int j=0;j<m1.c;j++)
            ans.a[i][j]=m1.a[i][j]-m2.a[i][j];
    return ans;
}

Matrix operator * (Matrix &m1,Matrix &m2){
    Matrix ans(m1.r,m2.c);
    ans.Fill(0);
    for(int i=0;i<m1.r;i++)
        for(int j=0;j<m2.c;j++)
            for(int k=0;k<m1.c;k++)
                ans.a[i][j]+=m1.a[i][k]*m2.a[k][j];
    return ans;
}

测试主函数

#include "usr.h"
int main(){
	int i,j;
	cin >> i >> j;
    Matrix m1(i,j),m2(i,j),m3(j,i);
    m1.Fill(1);
    m2.Fill(2);
	m3.Fill(0);
    for(int s = 0 ; s < i ; s++)
		for(int c = 0 ; c < j ; c++)
			if(s==c) m3.Set(s,c,s+1);
	cout << "m1 + m2 :" << endl ;
    (m1 + m2).Print();
	cout << "m1 - m2 :" << endl ;
    (m1 - m2).Print();
	cout << "m1 * m3 :" << endl ;
    (m1 * m3).Print();
}



版权声明:本文为m0_64839851原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。