鱼C论坛

 找回密码
 立即注册
查看: 1378|回复: 11

[已解决]C++模板类的符号重载

[复制链接]
发表于 2019-11-19 22:42:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 bin554385863 于 2019-11-19 22:56 编辑

这是我对照C++string写的一个数字串的类
重载的加号是用来拼接的,不知道为啥会出现数字溢出,


numbers.h
  1. #ifndef NUMBERS_H
  2. #define NUMBERS_H
  3. #include <iostream>
  4. #include <initializer_list>
  5. template <typename tp>
  6. class numbers
  7. {
  8. private:
  9.     tp *NUM;
  10.     size_t LENGTH;
  11. public:

  12.     numbers(const tp *carray, size_t sz);//数组构造

  13.     numbers() : LENGTH(0), NUM(nullptr) {} //默认构造*****

  14.     numbers(std::initializer_list<tp> list); //普通构造*****

  15.     numbers(numbers<tp> &arr); //复制构造*****

  16.     void pushback(const tp data); //尾部插入元素*****

  17.     size_t size(); //数字串的大小*****

  18.     tp &operator[](const size_t i); //重载索引下标符号[]*****

  19.     size_t find(tp num); //在对象中查找一个元素,返回索引*****

  20.     bool find(numbers<tp> &nums); //在对象中查找另一个对象,返回bool值*****

  21.     numbers<tp> operator+(numbers<tp>& nums);//拼接

  22.     numbers<tp> operator-(numbers<tp>& nums);//删除于第二个对象相同的元素

  23.     numbers<tp> operator-(tp num);//删除与num相同的元素

  24.     friend std::ostream &operator<<(std::ostream &os, numbers<tp> &arr)
  25.     //重载输出流符号<<
  26.     {
  27.         for (size_t i = 0; i < arr.size(); i++)
  28.         {
  29.             os << arr[i];
  30.         }
  31.         return os;
  32.     }
  33.     //析构函数
  34.     ~numbers();
  35. };
  36. #endif
复制代码

numbers.cpp
  1. #include "numbers.h"
  2. template <typename tp>
  3. numbers<tp>::numbers(const tp *carray, size_t sz) : LENGTH(sz) //数组构造
  4. {
  5.     NUM = new tp[LENGTH]{0};
  6.     for (size_t i = 0; i < LENGTH; i++)
  7.     {
  8.         *(NUM + i) = carray[i];
  9.     }
  10. }
  11. template <typename tp>
  12. numbers<tp>::numbers(std::initializer_list<tp> list) : LENGTH(list.size())
  13. //普通构造
  14. {
  15.     NUM = new tp[LENGTH];
  16.     for (size_t i = 0; i < LENGTH; i++)
  17.     {
  18.         NUM[i] = *(list.begin() + i);
  19.     }
  20. }
  21. template <typename tp>
  22. numbers<tp>::numbers(numbers<tp> &arr) //复制构造
  23. {
  24.     LENGTH = arr.LENGTH;
  25.     NUM = new tp[LENGTH];
  26.     for (size_t i = 0; i < LENGTH; i++)
  27.     {
  28.         *(NUM + i) = arr[i];
  29.     }
  30. }
  31. template <typename tp>
  32. void numbers<tp>::pushback(const tp data) //尾部插入元素
  33. {
  34.     tp *t_NUM = new tp[LENGTH + 1];
  35.     for (size_t i = 0; i < LENGTH; i++)
  36.     {
  37.         t_NUM[i] = NUM[i];
  38.     }
  39.     t_NUM[LENGTH] = data;
  40.     LENGTH += 1;
  41.     delete[] NUM;
  42.     NUM = t_NUM;
  43. }
  44. template <typename tp>
  45. size_t numbers<tp>::size() //取得对象的大小
  46. {
  47.     return LENGTH;
  48. }
  49. template <typename tp>
  50. tp &numbers<tp>::operator[](const size_t i) //重载索引符[]
  51. {
  52.     return NUM[i];
  53. }
  54. template <typename tp>
  55. size_t numbers<tp>::find(const tp num) //在对象里查找元素num是否存在
  56. //如果存在则返回出现的次数,否则返回0
  57. {
  58.     size_t count = 0;
  59.     for (size_t i = 0; i < LENGTH; i++)
  60.     {
  61.         if (num == NUM[i])
  62.         {
  63.             count++;
  64.         }
  65.     }
  66.     return count;
  67. }
  68. template <typename tp>
  69. bool numbers<tp>::find(numbers<tp> &nums) //查找子对象的元素是否存在于父对象中
  70. {
  71.     bool flag = true;
  72.     if (nums.LENGTH > LENGTH)
  73.     {
  74.         flag = false;
  75.     }
  76.     else
  77.     {
  78.         unsigned int count = 1;
  79.         for (size_t i = 0; i < nums.LENGTH; i++)
  80.         {
  81.             if (this->find(nums.NUM[i]))
  82.             {
  83.                 count++;
  84.             }
  85.             else
  86.             {
  87.                 flag = false;
  88.                 break;
  89.             }
  90.         }
  91.         if (count == nums.LENGTH)
  92.         {
  93.             flag = true;
  94.         }
  95.     }
  96.     return flag;
  97. }
  98. template <typename tp>
  99. numbers<tp> numbers<tp>::operator+(numbers<tp>& nums)
  100. {
  101.     numbers<tp> result(NUM, LENGTH);
  102.     for (size_t i = 0; i < nums.size(); i++)
  103.     {
  104.         result.pushback(nums[i]);
  105.     }
  106.     std::cout<<result;
  107.     return result;//在这里已经拼接成功
  108. }
  109. template <typename tp>
  110. numbers<tp>::~numbers() //析构函数
  111. {
  112.     delete[] NUM;
  113. }
  114. int main(int argc, char const *argv[])
  115. {
  116.     int arr[4] = {1, 2, 3, 4};
  117.     numbers<int> nums(arr, 4);
  118.     numbers<int> a = {5, 6, 7};
  119.     numbers<int> b;
  120.     b = a+nums;
  121.     std::cout<<b;//这里输出乱码
  122.     return 0;
  123. }
复制代码

最佳答案
2019-11-19 23:34:46
bin554385863 发表于 2019-11-19 23:31
我以为有个复制构造函数就不用了重载等号了

你不写,编译器的确会为你写一个,但是编译器为你写的这个版本是进行浅拷贝,在这里必须进行深拷贝
所以这里不能用编译器的默认版本,你必须提供你自己的版本
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-11-19 23:27:43 | 显示全部楼层
  1. #ifndef NUMBERS_H
  2. #define NUMBERS_H

  3. #include <iostream>
  4. #include <initializer_list>

  5. template <typename tp>
  6. class numbers
  7. {
  8. private:
  9.         tp *NUM;
  10.         size_t LENGTH;
  11. public:

  12.         numbers(const tp *carray, size_t sz);//数组构造

  13.         numbers(): LENGTH(0), NUM(nullptr) {} //默认构造*****

  14.         numbers(std::initializer_list<tp> list); //普通构造*****

  15.         numbers(numbers<tp> &arr); //复制构造*****

  16.         void pushback(const tp data); //尾部插入元素*****

  17.         size_t size(); //数字串的大小*****

  18.         tp &operator[](const size_t i); //重载索引下标符号[]*****

  19.         size_t find(tp num); //在对象中查找一个元素,返回索引*****

  20.         bool find(numbers<tp> &nums); //在对象中查找另一个对象,返回bool值*****

  21.         numbers<tp> operator+(numbers<tp>& nums);//拼接

  22.         numbers<tp> operator-(numbers<tp>& nums);//删除于第二个对象相同的元素

  23.         numbers<tp> operator-(tp num);//删除与num相同的元素





  24.         // 少了这个函数了
  25.         const numbers<tp> &operator=(const numbers<tp> &rhs)
  26.         {
  27.                 delete this->NUM;
  28.                 this->NUM = new tp[rhs.LENGTH];
  29.                 this->LENGTH = rhs.LENGTH;
  30.                 for(size_t i = 0; i < rhs.LENGTH; ++i)
  31.                         this->NUM[i] = rhs.NUM[i];
  32.                 return *this;
  33.         }




  34.         friend std::ostream &operator<<(std::ostream &os, numbers<tp> &arr)
  35.                 //重载输出流符号<<
  36.         {
  37.                 for(size_t i = 0; i < arr.size(); i++)
  38.                 {
  39.                         os << arr[i];
  40.                 }
  41.                 return os;
  42.         }
  43.         //析构函数
  44.         ~numbers();
  45. };
  46. #endif


  47. template <typename tp>
  48. numbers<tp>::numbers(const tp *carray, size_t sz): LENGTH(sz) //数组构造
  49. {
  50.         NUM = new tp[LENGTH]{0};
  51.         for(size_t i = 0; i < LENGTH; i++)
  52.         {
  53.                 *(NUM + i) = carray[i];
  54.         }
  55. }
  56. template <typename tp>
  57. numbers<tp>::numbers(std::initializer_list<tp> list): LENGTH(list.size())
  58. //普通构造
  59. {
  60.         NUM = new tp[LENGTH];
  61.         for(size_t i = 0; i < LENGTH; i++)
  62.         {
  63.                 NUM[i] = *(list.begin() + i);
  64.         }
  65. }
  66. template <typename tp>
  67. numbers<tp>::numbers(numbers<tp> &arr) //复制构造
  68. {
  69.         LENGTH = arr.LENGTH;
  70.         NUM = new tp[LENGTH];
  71.         for(size_t i = 0; i < LENGTH; i++)
  72.         {
  73.                 *(NUM + i) = arr[i];
  74.         }
  75. }
  76. template <typename tp>
  77. void numbers<tp>::pushback(const tp data) //尾部插入元素
  78. {
  79.         tp *t_NUM = new tp[LENGTH + 1];
  80.         for(size_t i = 0; i < LENGTH; i++)
  81.         {
  82.                 t_NUM[i] = NUM[i];
  83.         }
  84.         t_NUM[LENGTH] = data;
  85.         LENGTH += 1;
  86.         delete[] NUM;
  87.         NUM = t_NUM;
  88. }
  89. template <typename tp>
  90. size_t numbers<tp>::size() //取得对象的大小
  91. {
  92.         return LENGTH;
  93. }
  94. template <typename tp>
  95. tp &numbers<tp>::operator[](const size_t i) //重载索引符[]
  96. {
  97.         return NUM[i];
  98. }
  99. template <typename tp>
  100. size_t numbers<tp>::find(const tp num) //在对象里查找元素num是否存在
  101. //如果存在则返回出现的次数,否则返回0
  102. {
  103.         size_t count = 0;
  104.         for(size_t i = 0; i < LENGTH; i++)
  105.         {
  106.                 if(num == NUM[i])
  107.                 {
  108.                         count++;
  109.                 }
  110.         }
  111.         return count;
  112. }
  113. template <typename tp>
  114. bool numbers<tp>::find(numbers<tp> &nums) //查找子对象的元素是否存在于父对象中
  115. {
  116.         bool flag = true;
  117.         if(nums.LENGTH > LENGTH)
  118.         {
  119.                 flag = false;
  120.         }
  121.         else
  122.         {
  123.                 unsigned int count = 1;
  124.                 for(size_t i = 0; i < nums.LENGTH; i++)
  125.                 {
  126.                         if(this->find(nums.NUM[i]))
  127.                         {
  128.                                 count++;
  129.                         }
  130.                         else
  131.                         {
  132.                                 flag = false;
  133.                                 break;
  134.                         }
  135.                 }
  136.                 if(count == nums.LENGTH)
  137.                 {
  138.                         flag = true;
  139.                 }
  140.         }
  141.         return flag;
  142. }
  143. template <typename tp>
  144. numbers<tp> numbers<tp>::operator+(numbers<tp>& nums)
  145. {
  146.         numbers<tp> result(NUM, LENGTH);
  147.         for(size_t i = 0; i < nums.size(); i++)
  148.         {
  149.                 result.pushback(nums[i]);
  150.         }
  151.         //std::cout << result;
  152.         return result;//在这里已经拼接成功
  153. }
  154. template <typename tp>
  155. numbers<tp>::~numbers() //析构函数
  156. {
  157.         delete[] NUM;
  158. }
  159. int main(int argc, char const *argv[])
  160. {
  161.         int arr[4] = {1, 2, 3, 4};
  162.         numbers<int> nums(arr, 4);
  163.         numbers<int> a = {5, 6, 7};
  164.         numbers<int> b;
  165.         b = a + nums;
  166.         std::cout << b;//现在正常了
  167.         return 0;
  168. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-19 23:31:49 | 显示全部楼层


我以为有个复制构造函数就不用了重载等号了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-19 23:34:46 | 显示全部楼层    本楼为最佳答案   
bin554385863 发表于 2019-11-19 23:31
我以为有个复制构造函数就不用了重载等号了

你不写,编译器的确会为你写一个,但是编译器为你写的这个版本是进行浅拷贝,在这里必须进行深拷贝
所以这里不能用编译器的默认版本,你必须提供你自己的版本
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-19 23:36:56 | 显示全部楼层
人造人 发表于 2019-11-19 23:34
你不写,编译器的确会为你写一个,但是编译器为你写的这个版本是进行浅拷贝,在这里必须进行深拷贝
所以 ...

原来这样,就这个问题折腾了我俩小时
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-19 23:37:50 | 显示全部楼层
bin554385863 发表于 2019-11-19 23:36
原来这样,就这个问题折腾了我俩小时

^_^
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-19 23:41:25 | 显示全部楼层

谢谢了,不懂得再问你哈,貌似论坛里C++不怎么多啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-19 23:44:19 | 显示全部楼层
bin554385863 发表于 2019-11-19 23:41
谢谢了,不懂得再问你哈,貌似论坛里C++不怎么多啊

嗯,的确不多了,都去python版块了
^_^
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-19 23:48:24 | 显示全部楼层
人造人 发表于 2019-11-19 23:44
嗯,的确不多了,都去python版块了
^_^

Python么,算了没兴趣,我自己的计划是C---C++----C#
不过我感觉C++的坑太难爬了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-19 23:52:07 | 显示全部楼层
bin554385863 发表于 2019-11-19 23:48
Python么,算了没兴趣,我自己的计划是C---C++----C#
不过我感觉C++的坑太难爬了

我也不喜欢python


“不过我感觉C++的坑太难爬了”
还行吧,推荐一本书《C++ Primer Plus (第6版)中文版》
这本书真的不错
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-11-19 23:58:59 | 显示全部楼层
本帖最后由 bin554385863 于 2019-11-20 00:01 编辑


我有
还有侯捷的effective C++
plus 学了一半了,不过我本来只想写个简简单单的类练习一下,没想到写到模板类上面去了,我现在都是一边翻书一边写.不然都写不下去(╯‵□′)╯︵┻━┻
还有迭代器目前实在搞不定
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-20 01:29:31 | 显示全部楼层
bin554385863 发表于 2019-11-19 23:58
我有
还有侯捷的effective C++
plus 学了一半了,不过我本来只想写个简简单单的类练习一下,没想到写到 ...

不用着急,慢慢来吧
这玩意急也没用
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-26 20:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表