鱼C论坛

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

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

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

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

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

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

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


numbers.h
#ifndef NUMBERS_H
#define NUMBERS_H
#include <iostream>
#include <initializer_list>
template <typename tp>
class numbers
{
private:
    tp *NUM;
    size_t LENGTH;
public:

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

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

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

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

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

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

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

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

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

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

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

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

    friend std::ostream &operator<<(std::ostream &os, numbers<tp> &arr)
    //重载输出流符号<<
    {
        for (size_t i = 0; i < arr.size(); i++)
        {
            os << arr[i];
        }
        return os;
    }
    //析构函数
    ~numbers();
};
#endif
numbers.cpp
#include "numbers.h"
template <typename tp>
numbers<tp>::numbers(const tp *carray, size_t sz) : LENGTH(sz) //数组构造
{
    NUM = new tp[LENGTH]{0};
    for (size_t i = 0; i < LENGTH; i++)
    {
        *(NUM + i) = carray[i];
    }
}
template <typename tp>
numbers<tp>::numbers(std::initializer_list<tp> list) : LENGTH(list.size())
//普通构造
{
    NUM = new tp[LENGTH];
    for (size_t i = 0; i < LENGTH; i++)
    {
        NUM[i] = *(list.begin() + i);
    }
}
template <typename tp>
numbers<tp>::numbers(numbers<tp> &arr) //复制构造
{
    LENGTH = arr.LENGTH;
    NUM = new tp[LENGTH];
    for (size_t i = 0; i < LENGTH; i++)
    {
        *(NUM + i) = arr[i];
    }
}
template <typename tp>
void numbers<tp>::pushback(const tp data) //尾部插入元素
{
    tp *t_NUM = new tp[LENGTH + 1];
    for (size_t i = 0; i < LENGTH; i++)
    {
        t_NUM[i] = NUM[i];
    }
    t_NUM[LENGTH] = data;
    LENGTH += 1;
    delete[] NUM;
    NUM = t_NUM;
}
template <typename tp>
size_t numbers<tp>::size() //取得对象的大小
{
    return LENGTH;
}
template <typename tp>
tp &numbers<tp>::operator[](const size_t i) //重载索引符[]
{
    return NUM[i];
}
template <typename tp>
size_t numbers<tp>::find(const tp num) //在对象里查找元素num是否存在
//如果存在则返回出现的次数,否则返回0
{
    size_t count = 0;
    for (size_t i = 0; i < LENGTH; i++)
    {
        if (num == NUM[i])
        {
            count++;
        }
    }
    return count;
}
template <typename tp>
bool numbers<tp>::find(numbers<tp> &nums) //查找子对象的元素是否存在于父对象中
{
    bool flag = true;
    if (nums.LENGTH > LENGTH)
    {
        flag = false;
    }
    else
    {
        unsigned int count = 1;
        for (size_t i = 0; i < nums.LENGTH; i++)
        {
            if (this->find(nums.NUM[i]))
            {
                count++;
            }
            else
            {
                flag = false;
                break;
            }
        }
        if (count == nums.LENGTH)
        {
            flag = true;
        }
    }
    return flag;
}
template <typename tp>
numbers<tp> numbers<tp>::operator+(numbers<tp>& nums)
{
    numbers<tp> result(NUM, LENGTH);
    for (size_t i = 0; i < nums.size(); i++)
    {
        result.pushback(nums[i]);
    }
    std::cout<<result;
    return result;//在这里已经拼接成功
}
template <typename tp>
numbers<tp>::~numbers() //析构函数
{
    delete[] NUM;
}
int main(int argc, char const *argv[])
{
    int arr[4] = {1, 2, 3, 4};
    numbers<int> nums(arr, 4);
    numbers<int> a = {5, 6, 7};
    numbers<int> b;
    b = a+nums;
    std::cout<<b;//这里输出乱码
    return 0;
}
最佳答案
2019-11-19 23:34:46
bin554385863 发表于 2019-11-19 23:31
我以为有个复制构造函数就不用了重载等号了

你不写,编译器的确会为你写一个,但是编译器为你写的这个版本是进行浅拷贝,在这里必须进行深拷贝
所以这里不能用编译器的默认版本,你必须提供你自己的版本
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

#include <iostream>
#include <initializer_list>

template <typename tp>
class numbers
{
private:
        tp *NUM;
        size_t LENGTH;
public:

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

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

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

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

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

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

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

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

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

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

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

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





        // 少了这个函数了
        const numbers<tp> &operator=(const numbers<tp> &rhs)
        {
                delete this->NUM;
                this->NUM = new tp[rhs.LENGTH];
                this->LENGTH = rhs.LENGTH;
                for(size_t i = 0; i < rhs.LENGTH; ++i)
                        this->NUM[i] = rhs.NUM[i];
                return *this;
        }




        friend std::ostream &operator<<(std::ostream &os, numbers<tp> &arr)
                //重载输出流符号<<
        {
                for(size_t i = 0; i < arr.size(); i++)
                {
                        os << arr[i];
                }
                return os;
        }
        //析构函数
        ~numbers();
};
#endif


template <typename tp>
numbers<tp>::numbers(const tp *carray, size_t sz): LENGTH(sz) //数组构造
{
        NUM = new tp[LENGTH]{0};
        for(size_t i = 0; i < LENGTH; i++)
        {
                *(NUM + i) = carray[i];
        }
}
template <typename tp>
numbers<tp>::numbers(std::initializer_list<tp> list): LENGTH(list.size())
//普通构造
{
        NUM = new tp[LENGTH];
        for(size_t i = 0; i < LENGTH; i++)
        {
                NUM[i] = *(list.begin() + i);
        }
}
template <typename tp>
numbers<tp>::numbers(numbers<tp> &arr) //复制构造
{
        LENGTH = arr.LENGTH;
        NUM = new tp[LENGTH];
        for(size_t i = 0; i < LENGTH; i++)
        {
                *(NUM + i) = arr[i];
        }
}
template <typename tp>
void numbers<tp>::pushback(const tp data) //尾部插入元素
{
        tp *t_NUM = new tp[LENGTH + 1];
        for(size_t i = 0; i < LENGTH; i++)
        {
                t_NUM[i] = NUM[i];
        }
        t_NUM[LENGTH] = data;
        LENGTH += 1;
        delete[] NUM;
        NUM = t_NUM;
}
template <typename tp>
size_t numbers<tp>::size() //取得对象的大小
{
        return LENGTH;
}
template <typename tp>
tp &numbers<tp>::operator[](const size_t i) //重载索引符[]
{
        return NUM[i];
}
template <typename tp>
size_t numbers<tp>::find(const tp num) //在对象里查找元素num是否存在
//如果存在则返回出现的次数,否则返回0
{
        size_t count = 0;
        for(size_t i = 0; i < LENGTH; i++)
        {
                if(num == NUM[i])
                {
                        count++;
                }
        }
        return count;
}
template <typename tp>
bool numbers<tp>::find(numbers<tp> &nums) //查找子对象的元素是否存在于父对象中
{
        bool flag = true;
        if(nums.LENGTH > LENGTH)
        {
                flag = false;
        }
        else
        {
                unsigned int count = 1;
                for(size_t i = 0; i < nums.LENGTH; i++)
                {
                        if(this->find(nums.NUM[i]))
                        {
                                count++;
                        }
                        else
                        {
                                flag = false;
                                break;
                        }
                }
                if(count == nums.LENGTH)
                {
                        flag = true;
                }
        }
        return flag;
}
template <typename tp>
numbers<tp> numbers<tp>::operator+(numbers<tp>& nums)
{
        numbers<tp> result(NUM, LENGTH);
        for(size_t i = 0; i < nums.size(); i++)
        {
                result.pushback(nums[i]);
        }
        //std::cout << result;
        return result;//在这里已经拼接成功
}
template <typename tp>
numbers<tp>::~numbers() //析构函数
{
        delete[] NUM;
}
int main(int argc, char const *argv[])
{
        int arr[4] = {1, 2, 3, 4};
        numbers<int> nums(arr, 4);
        numbers<int> a = {5, 6, 7};
        numbers<int> b;
        b = a + nums;
        std::cout << b;//现在正常了
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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


我以为有个复制构造函数就不用了重载等号了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

你不写,编译器的确会为你写一个,但是编译器为你写的这个版本是进行浅拷贝,在这里必须进行深拷贝
所以这里不能用编译器的默认版本,你必须提供你自己的版本
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

原来这样,就这个问题折腾了我俩小时
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

谢谢了,不懂得再问你哈,貌似论坛里C++不怎么多啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

嗯,的确不多了,都去python版块了
^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

Python么,算了没兴趣,我自己的计划是C---C++----C#
不过我感觉C++的坑太难爬了
想知道小甲鱼最近在做啥?请访问 -> 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版)中文版》
这本书真的不错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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


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

使用道具 举报

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

不用着急,慢慢来吧
这玩意急也没用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-10-4 23:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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