[c++]代码库
/*
C++构造函数和运算符重载程序例案
*/
//程序1:
#include<iostream>
#include<string>
using namespace std;
class Person{
string name;
bool gender;
int age;
Person *lover;//注意这里是指针
public:
Person(const char *n,bool g)
:name(n),gender(g),age(0),lover(NULL){}
void show();
void growup(int years);
void marry(Person &p);
};
void Person::show()
{
cout<<"大家好,我是"<<(gender?"帅哥":"美女")<<name<<',';
cout<<"我今年"<<age<<"岁!";
if(lover==NULL)
cout<<"目前单身!"<<endl;
else
cout<<"爱人是"<<lover->name<<’!’<<endl;
cout<<endl;
}
void Person::growup(int years)
{
age+=years;
}
void Person::marry(Person &p)
{
lover=&p;
p.lover=this;//this表示当前对象
cout<<name<<"和"<<p.name<<"结婚"<<endl;
}
int main()
{
Person a("芙蓉",false);
Person b("春哥",true);
a.growup(19);
a.show();
Person e();//声明一个函数,所以一般不要在声明一个对象之后加括号(),放置引起歧义
//e().show();
b.marry(a);
a.show();
}
Person e()
{
string name;
bool gender;
int age;
cout<<"请出入姓名、性别和年龄:";
cin>>name>>gender>>age;
Person input(name.c_str(),gender);//类似于Person b("春哥",true);
input.growup(age);
return input;
}
//输出结果:
//大家好,我是美女芙蓉,我今年19岁!目前单身
//春哥和芙蓉结婚
//大家好,我是美女芙蓉,我今年19岁!爱人是春哥
---------------------------------------------------------------------------------------------------------------------------------
//程序2:
#include<iostream>
using namespace std;
class fraction{
int a;
int b;
public:
fraction(int m=0,int n=1):a(m),b(n){}
friend ostream &operator<<(ostream &o,const fraction &f)
{
o<<f.a<<'/'<<f.b;
return o;
}
friend fraction operator+(const fraction &A,const fraction& B)
{//这里返回值不加&,因为返回值需要复制,重新开辟空间保存,因为返回局部变量res,出了作用域就会释放,故需要复制一份
fraction res(A.a*B.b+B.a*A.b,A.b*B.b);
return res;
}
/*
//这里写成友员
friend fraction operator*(const fraction &A,const fraction& B)
{//这里返回值不加&,因为返回值需要复制,重新开辟空间保存
fraction res(A.a*B.a,A.b*B.b);
return res;
}
*/
//这里写成成员函数,可以使用类里面的成员(作为当前对象),成员比友员少一个参数
fraction operator*(const fraction &A)
{
return fraction (a*A.a,b*A.b);//匿名对象
}
};
int main()
{
fraction x(2,3);
fraction y(3,4);
cout<<x+y<<endl;//由于这里是x+y,所加的结果是一个临时值,
//故对于重载运算符+、<<里面都必须加const 防止临时值消失
cout<<x*y<<endl;
}
---------------------------------------------------------------------------------------------------------------------------------
//3.临时对象
Teacher t1(“A”,102);
Teacher t2=t1;//将会调用拷贝构造函数
Teacher t3=Teacher (“B”,101);
//用临时对象来初始化一个新对象,编译器一般会优化成直接用创建临时对象的参数来创建新对象
//临时对象,当时创建,当时释放,所以建议使用临时对象
------------------------------------------------------------------------------------------------------------------------------程序3:
//一般情况下,一个函数可以写成成员函数,也可以写成非成员函数
//当写成成员函数时,可以少一个参数(当前对象this),如下面return !a,其实就是!(this->a)
#include<iostream>
using namespace std;
class fraction{
int a;
int b;
public:
fraction(int m=0,int n=1):a(m),b(n){}
friend ostream &operator<<(ostream &o,const fraction &f)
{
o<<f.a<<'/'<<f.b;
return o;
}
friend fraction operator~(const fraction& f);//友员,不是成员函数,必须有参数(表示哪个对象)
bool operator!()const//这里写成成员函数,故参数为空,表示当前对象
{
return !a;
//return !(this->a);
}
};
fraction operator~(const fraction &f)//因为是非成员函数,所以不需要加”类名::”
{
return fraction (f.b,f.a);
}
int main()
{
fraction f1(0,3);
cout<<f1<<endl;
cout<<!f1<<endl;
cout<<~f1<<endl;
cout<<~10<<endl;
return 0;
}
//程序4:
/*什么时候需要重载“=”,以及什么时候要写拷贝构造函数和析构函数:
当有指针成员指向动态内存时;
因为动态分配了内存所以要释放(即需要写析构函数)
*/
//注意:因为类里面有指针变量,所以必须要写拷贝构造函数;
//这是因为,如果不写,那么将调用默认拷贝构造函数,默认拷贝构造函
//只是复制,其他什么也不做,这样两个指针指向同一片空间,但是又
//因为构造了两个对象,会调用析构函数,就会使得同一片空间被释放
//两次(double free),产生错误;而自己写的拷贝构造函数,会重新
//开辟空间,这样就不会倒置错误
#include<iostream>
using namespace std;
class Stack{
int *a;//指针成员,会动态的指向内存
int max;
int len;
public:
Stack(int n):a(new int[n]),max(n),len(0){}
Stack(const Stack& s):a(new int [s.max]),max(s.max),len(s.len){}
~Stack(){delete []a;}
Stack& push(const int& m)
{
if(len>=max) throw 0/*"栈已满!"*/;
a[len++]=m;
return *this;
}
void print()const/*加const防止当前对象被修改*/
{
for(int i=0;i<len;i++)
cout<<a[i]<<' ';
cout<<endl;
}
//对“=”进行运算符重载,"="只能写成成员函数
//其中一个参数默认为当前对象的参数
//重载“=”表示动态赋值,故要重新匹配空间,保证和原来的空间大小一样
Stack &operator=(const Stack &/*引用表示不需要在传参数的时候复制*/rs)
{
delete []a;
a=new int [rs.max];
max=rs.max;
len=rs.len;
for(int i=0;i<len;i++) a[i]=rs.a[i];
//return *this;//可要可不要
}
};
int main()
{
Stack t1(10);
//注意:这里对于t2的初始化必须要在t1.push()之前
//否则如果将Stack t2(t1);放在t1.push()之后,由于已经入栈,故栈的空间已经被占用
Stack t2(t1);
t1.push(1).push(2).push(3).push(4);
t2.push(5).push(6).push(7).push(8);
t1.print();
t2.print();
Stack t3(6);
t3=t2;
t3.print();
}
//程序5:
//重载前”++”和后”++”:
//规定后”++”参数多一个(int){表示哑元},由此区别前++
#include<iostream>
using namespace std;
class F{
int a;
int b;
public:
F(int m=0,int n=1):a(m),b(n){}
F &operator++(){a+=b;return *this;}//前++,返回值有引用,新值就作为当前值用,不用copy
F operator++(int){F old(*this);a+=b;return old;}//后++,没有引用,用旧值计算并保留旧值,故 //需要copy
//注意:重载“<<”(输出运算符)时,如果写成两个参数,就表示不是成员函数,所以必//须加friend,表示友元,才能访问类里面的私有成员,同时第二个参数对于重载后”++” 和”~”的时候必须要加const
friend ostream &operator<<(ostream &o,const F &f)
{
o<<f.a<<'/'<<f.b;
return o;
}
//重载类型转换运算符,返回值可以不写(和重载运算符一致)
operator double(){return 1.0*a/b;}
operator bool(){return a;}
};
int main()
{
F f(2,3);
cout<<++f<<endl;
cout<<(f++)<<endl;//当是后++时,重载“<<”时第二个参数前必须加const
cout<<f<<endl;
cout<<double(f)<<endl;
cout<<bool(f)<<endl;
return 0;
}