[C++] C++构造函数和运算符重载程序例案 →→→→→进入此内容的聊天室

来自 , 2021-04-10, 写在 C++, 查看 146 次.
URL http://www.code666.cn/view/39dcaf7a
  1. /*
  2. C++构造函数和运算符重载程序例案
  3. */
  4. //程序1:
  5. #include<iostream>
  6. #include<string>
  7. using namespace std;
  8. class Person{
  9.         string name;
  10.         bool gender;
  11.         int age;
  12.         Person *lover;//注意这里是指针
  13. public:
  14.         Person(const char *n,bool g)
  15.                                 :name(n),gender(g),age(0),lover(NULL){}
  16.         void show();
  17.         void growup(int years);
  18.         void marry(Person &p);
  19. };
  20. void Person::show()
  21. {
  22.         cout<<"大家好,我是"<<(gender?"帅哥":"美女")<<name<<',';
  23.         cout<<"我今年"<<age<<"岁!";
  24.         if(lover==NULL)
  25.                 cout<<"目前单身!"<<endl;
  26.         else
  27.                 cout<<"爱人是"<<lover->name<<!<<endl;
  28.         cout<<endl;
  29. }
  30. void Person::growup(int years)
  31. {
  32.         age+=years;
  33. }
  34. void Person::marry(Person &p)
  35. {
  36.         lover=&p;
  37.         p.lover=this;//this表示当前对象
  38.         cout<<name<<"和"<<p.name<<"结婚"<<endl;     
  39. }
  40.  
  41. int main()
  42. {
  43.         Person a("芙蓉",false);
  44.         Person b("春哥",true);
  45.         a.growup(19);
  46.         a.show();
  47.         Person e();//声明一个函数,所以一般不要在声明一个对象之后加括号(),放置引起歧义
  48.         //e().show();
  49.         b.marry(a);
  50.         a.show();
  51. }
  52.  
  53. Person e()
  54. {
  55.         string name;
  56.         bool gender;
  57.         int age;
  58.         cout<<"请出入姓名、性别和年龄:";
  59.         cin>>name>>gender>>age;
  60.         Person input(name.c_str(),gender);//类似于Person b("春哥",true);
  61.         input.growup(age);
  62.         return input;
  63. }
  64.  
  65. //输出结果:
  66. //大家好,我是美女芙蓉,我今年19岁!目前单身
  67.  
  68. //春哥和芙蓉结婚
  69. //大家好,我是美女芙蓉,我今年19岁!爱人是春哥
  70.  
  71.  
  72.  
  73. ---------------------------------------------------------------------------------------------------------------------------------
  74. //程序2:
  75. #include<iostream>
  76. using namespace std;
  77. class fraction{
  78.   int a;
  79.   int b;
  80. public:
  81.   fraction(int m=0,int n=1):a(m),b(n){}
  82.   friend ostream &operator<<(ostream &o,const fraction &f)
  83.   {
  84.     o<<f.a<<'/'<<f.b;
  85.     return o;
  86.   }
  87.   friend fraction operator+(const fraction &A,const fraction& B)
  88.   {//这里返回值不加&,因为返回值需要复制,重新开辟空间保存,因为返回局部变量res,出了作用域就会释放,故需要复制一份
  89.     fraction res(A.a*B.b+B.a*A.b,A.b*B.b);
  90.     return res;
  91.   }
  92.  
  93.   /*
  94.   //这里写成友员
  95.   friend fraction operator*(const fraction &A,const fraction& B)
  96.   {//这里返回值不加&,因为返回值需要复制,重新开辟空间保存
  97.     fraction res(A.a*B.a,A.b*B.b);
  98.     return res;
  99.   }
  100.   */
  101.   //这里写成成员函数,可以使用类里面的成员(作为当前对象),成员比友员少一个参数
  102.   fraction operator*(const fraction &A)
  103.   {
  104.     return fraction (a*A.a,b*A.b);//匿名对象
  105.   }
  106. };
  107. int main()
  108. {
  109.   fraction x(2,3);
  110.   fraction y(3,4);
  111.   cout<<x+y<<endl;//由于这里是x+y,所加的结果是一个临时值,
  112.   //故对于重载运算符+、<<里面都必须加const 防止临时值消失
  113.   cout<<x*y<<endl;
  114. }
  115.  
  116.  
  117.  
  118.  
  119. ---------------------------------------------------------------------------------------------------------------------------------
  120. //3.临时对象
  121.  
  122. Teacher t1(“A”,102);
  123. Teacher t2=t1;//将会调用拷贝构造函数
  124. Teacher t3=Teacher (“B”,101);
  125. //用临时对象来初始化一个新对象,编译器一般会优化成直接用创建临时对象的参数来创建新对象
  126. //临时对象,当时创建,当时释放,所以建议使用临时对象
  127.  
  128.  
  129.  
  130.  
  131. ------------------------------------------------------------------------------------------------------------------------------程序3
  132. //一般情况下,一个函数可以写成成员函数,也可以写成非成员函数
  133. //当写成成员函数时,可以少一个参数(当前对象this),如下面return !a,其实就是!(this->a)
  134. #include<iostream>
  135. using namespace std;
  136. class fraction{
  137.   int a;
  138.   int b;
  139. public:
  140.   fraction(int m=0,int n=1):a(m),b(n){}
  141.   friend ostream &operator<<(ostream &o,const fraction &f)
  142.   {
  143.     o<<f.a<<'/'<<f.b;
  144.     return o;
  145.   }
  146.   friend fraction operator~(const fraction& f);//友员,不是成员函数,必须有参数(表示哪个对象)
  147.   bool operator!()const//这里写成成员函数,故参数为空,表示当前对象
  148.   {
  149.     return !a;
  150.     //return !(this->a);
  151.   }
  152. };
  153. fraction operator~(const fraction &f)//因为是非成员函数,所以不需要加”类名::”
  154. {
  155.   return fraction (f.b,f.a);
  156. }
  157. int main()
  158. {
  159.   fraction f1(0,3);
  160.   cout<<f1<<endl;
  161.   cout<<!f1<<endl;
  162.   cout<<~f1<<endl;
  163.   cout<<~10<<endl;
  164.   return 0;
  165. }
  166.  
  167.  
  168.  
  169.  
  170. //程序4:
  171. /*什么时候需要重载“=”,以及什么时候要写拷贝构造函数和析构函数:
  172.  当有指针成员指向动态内存时;
  173.  因为动态分配了内存所以要释放(即需要写析构函数)
  174.  */
  175. //注意:因为类里面有指针变量,所以必须要写拷贝构造函数;
  176. //这是因为,如果不写,那么将调用默认拷贝构造函数,默认拷贝构造函
  177. //只是复制,其他什么也不做,这样两个指针指向同一片空间,但是又
  178. //因为构造了两个对象,会调用析构函数,就会使得同一片空间被释放
  179. //两次(double free),产生错误;而自己写的拷贝构造函数,会重新
  180. //开辟空间,这样就不会倒置错误
  181. #include<iostream>
  182. using namespace std;
  183. class Stack{
  184.   int *a;//指针成员,会动态的指向内存  
  185.   int max;
  186.   int len;
  187. public:
  188.   Stack(int n):a(new int[n]),max(n),len(0){}
  189.   Stack(const Stack& s):a(new int [s.max]),max(s.max),len(s.len){}
  190.   ~Stack(){delete []a;}
  191.   Stack& push(const int& m)
  192.   {
  193.     if(len>=max) throw 0/*"栈已满!"*/;
  194.     a[len++]=m;
  195.     return *this;
  196.   }
  197.   void print()const/*加const防止当前对象被修改*/
  198.   {
  199.     for(int i=0;i<len;i++)
  200.       cout<<a[i]<<' ';
  201.     cout<<endl;
  202.   }
  203.   //对“=”进行运算符重载,"="只能写成成员函数
  204.   //其中一个参数默认为当前对象的参数
  205.   //重载“=”表示动态赋值,故要重新匹配空间,保证和原来的空间大小一样
  206.   Stack &operator=(const Stack &/*引用表示不需要在传参数的时候复制*/rs)
  207.   {
  208.     delete []a;
  209.     a=new int [rs.max];
  210.     max=rs.max;
  211.     len=rs.len;
  212.     for(int i=0;i<len;i++) a[i]=rs.a[i];
  213.     //return *this;//可要可不要
  214.   }
  215.  
  216. };
  217. int main()
  218. {
  219.   Stack t1(10);
  220.   //注意:这里对于t2的初始化必须要在t1.push()之前
  221.   //否则如果将Stack t2(t1);放在t1.push()之后,由于已经入栈,故栈的空间已经被占用
  222.   Stack t2(t1);
  223.   t1.push(1).push(2).push(3).push(4);
  224.   t2.push(5).push(6).push(7).push(8);
  225.   t1.print();
  226.   t2.print();
  227.   Stack t3(6);
  228.   t3=t2;
  229.   t3.print();
  230. }
  231.  
  232.  
  233.  
  234.  
  235. //程序5:
  236. //重载前”++”和后”++”:
  237. //规定后”++”参数多一个(int){表示哑元},由此区别前++
  238. #include<iostream>
  239. using namespace std;
  240. class F{
  241.   int a;
  242.   int b;
  243. public:
  244.   F(int m=0,int n=1):a(m),b(n){}
  245.   F &operator++(){a+=b;return *this;}//前++,返回值有引用,新值就作为当前值用,不用copy
  246.   F operator++(int){F old(*this);a+=b;return old;}//后++,没有引用,用旧值计算并保留旧值,故  //需要copy
  247.   //注意:重载“<<”(输出运算符)时,如果写成两个参数,就表示不是成员函数,所以必//须加friend,表示友元,才能访问类里面的私有成员,同时第二个参数对于重载后”++” 和”~”的时候必须要加const
  248.   friend ostream &operator<<(ostream &o,const F &f)
  249.   {
  250.     o<<f.a<<'/'<<f.b;
  251.     return o;
  252.   }
  253.   //重载类型转换运算符,返回值可以不写(和重载运算符一致)
  254.   operator double(){return 1.0*a/b;}
  255.   operator bool(){return a;}
  256. };
  257. int main()
  258. {
  259.   F f(2,3);
  260.   cout<<++f<<endl;
  261.   cout<<(f++)<<endl;//当是后++时,重载“<<”时第二个参数前必须加const
  262.   cout<<f<<endl;
  263.   cout<<double(f)<<endl;
  264.   cout<<bool(f)<<endl;
  265.   return 0;
  266. }
  267.  

回复 "C++构造函数和运算符重载程序例案"

这儿你可以回复上面这条便签

captcha