【问题标题】:operators overloading, odd seg fault, classes, c++运算符重载,奇数段错误,类,C++
【发布时间】:2015-11-10 09:20:18
【问题描述】:

我的导师给了我一个关于重载运算符的练习。他给了我无法更改的 int main() 函数。我应该编写函数等,以便代码可以工作。不幸的是我有一个段错误。我注意到如果

 TSeries series4=series1(2,4);
 cout << "Series4: " << series4 << endl;

行被评论它或多或少的工作。我将非常感谢您的帮助。

#include <iostream>
class TSeries {
public:
    TSeries()
    {
        _size = 0;
        _capacity = 0;
        _tab = NULL;
    }


    TSeries(float *tab, const int size)
    {
        _tab = new float[size];
        for (int i = 0; i < size; i++) _tab[i] = tab[i];
        _size = size;
        _capacity = 0;
    }

    ~TSeries() { delete[] _tab; }

    TSeries & operator+=(float value) { return insert(value); }
    TSeries & operator,(float value) { return insert(value); }
    TSeries & operator+(const TSeries & s)
    {
        //  if(this->_size != s._size) std::cout<<"Size doesn't match!"<<std::endl;
        /*else
        {
        std::cout<<"whee";
        for(int i; i<this->_size;i++)
        {
        //this->_tab[i] += s._tab[i];
        std::cout<<"nothing";
        }
        return *this;
        }*/
        //std::cout<<"sth";
    }

    TSeries & operator()(int position1, int position2)
    {
        // return *this;
    }

    TSeries & insert(float k)
    {
        if (_size >= _capacity) Enlarge();
        _tab[_size++] = k;
        return *this;
    }
    friend std::ostream & operator<<(std::ostream & out, const TSeries & s);


private:
    int _size, _capacity;
    float *_tab, *_itr;
    static int _nr;

    void Enlarge()
    {
        _capacity = 2 * _capacity + 1;
        float *tmp = new float[_capacity];

        for (int i = 0; i < _size; ++i)
        {
            tmp[i] = _tab[i];
        }
        delete[] _tab;
        _tab = tmp;
    }
};

std::ostream & operator<<(std::ostream & out, const TSeries & s)
{
    int przedostatni = s._size - 1;
    out << "(";
    for (int i = 0; i < s._size; i++)
    {
        out << (int)s._tab[i];
        if (i != przedostatni)
            out << ",";
    }
    out << ")" << std::endl;
}

using namespace std;
int main(int argc, char **argv) {
    TSeries series1;
    series1 += 1., 2., 4., 2.;
    cout << "Series1: " << series1 << endl;

    const int size = 7;
    float tab[size] = { 3.,3.,3.,4.,5.,1.,0. };
    const TSeries series2(tab, size);
    cout << "Series2: " << series2 << endl << endl;


    TSeries series3 = series1 + series2;
    cout << "Series3: " << series3 << endl << endl;

    series1 += 1., 0., 3.;
    series3 = series1 + series2;
    cout << "           " << series1 << endl;
    cout << "          +" << series2 << endl;
    cout << "        ---------------------" << endl;
    cout << "Series3:   " << series3 << endl << endl;

    TSeries series4 = series1(2, 4);
    cout << "Series4: " << series4 << endl;

    return 0;
}

/* output required:
Series1: (1,2,4,2)
Series2: (3,3,3,4,5,1,0)

Size doesn't match!
Series3: ()

(1,2,4,2,1,0,3)
+(3,3,3,4,5,1,0)
---------------------
Series3:   (4,5,7,6,6,1,3)

Series4: (4,2)
*/

【问题讨论】:

  • 表达式series1 += 1.,2.,4.,2. 不会像您期望的那样做,除非您期望它与series1 += 2. 相同。阅读the comma operator
  • 我希望它像多重插入函数一样工作,这意味着首先有 series1 +=1 然后是 seires1 += 2 等。
  • 另外,你真的应该阅读一下the rules of three, five and zero
  • Good ol' 逗号运算符:它计算第一个表达式,丢弃它,计算第二个表达式并返回它。这么好的东西!
  • 还有其他建议吗?

标签: c++ class segmentation-fault operator-overloading


【解决方案1】:
  1. std::ostream &amp; operator&lt;&lt;(std::ostream &amp; out, const TSeries &amp; s) 不返回任何内容。请在函数末尾添加return out
  2. operator()operator+ 都应该以 return *this 结尾
  3. 正如 Devolus 已经指出的那样:您没有复制构造函数,也没有定义 operator=(const TSeries&amp;)
  4. 您可以使用memcpy 更快地复制数组。#
  5. operator+(const TSeries&amp;) 中 for 循环中的 i 未初始化。
  6. 您的operator(int, int) 当前确实更改了原始对象。这似乎不对。

代码:

#include <iostream>
class TSeries {
public:
    TSeries()
    {
        _size = 0;
        _capacity = 0;

        _tab = NULL;
    }


    TSeries(float *tab, const int size)
    {
        _size = size;
        _capacity = 0;

        _tab = new float[size];
        memcpy(_tab, tab, _size*sizeof(float));
    }

    TSeries(const TSeries& other)
    {
        _size = other._size;
        _capacity = other._capacity;

        _tab = new float[_size];
        memcpy(_tab, other._tab, _size*sizeof(float));
    }

    ~TSeries() 
    { 
        delete[] _tab;
    }

    TSeries & operator+=(float value) { return insert(value); }
    TSeries & operator,(float value) { return insert(value); }
    TSeries & operator+(const TSeries & other)
    {
        if (this->_size != other._size)
        {
            std::cout << "Size doesn't match!" << std::endl;
        }
        else
        {
            //std::cout << "whee";
            for (int i = 0; i < this->_size; i++)
            {
                _tab[i] += other._tab[i];
                //std::cout << "nothing";
            }
        }
        //std::cout<<"sth";
        return *this;
    }

    TSeries& operator=(const TSeries& other)
    {
        _size = other._size;
        _capacity = other._capacity;
        //Create tmp in case of self-assignment
        float *tmp = new float[_capacity];
        memcpy(tmp, other._tab, _size*sizeof(float));
        delete[] _tab;
        _tab = tmp;
        return *this;
    }

    TSeries operator()(int position1, int position2)
    {
        //TODO: Range-Check
        return TSeries(_tab + position1, position2 - position1);
    }

    TSeries & insert(float k)
    {
        if (_size >= _capacity) Enlarge();
        _tab[_size++] = k;
        return *this;
    }
    friend std::ostream & operator<<(std::ostream & out, const TSeries & s);


private:
    int _size, _capacity;
    float *_tab, *_itr;
    static int _nr;

    void Enlarge()
    {
        _capacity = 2 * _capacity + 1;
        float *tmp = new float[_capacity];
        memcpy(tmp, _tab, _size*sizeof(float));
        delete[] _tab;
        _tab = tmp;
    }
};

std::ostream & operator<<(std::ostream & out, const TSeries & s)
{
    int przedostatni = s._size - 1;
    out << "(";
    for (int i = 0; i < s._size; i++)
    {
        out << (int)s._tab[i];
        if (i != przedostatni)
            out << ",";
    }
    out << ")" << std::endl;
    return out;
}

using namespace std;
int main(int argc, char **argv) {
    TSeries series1;
    series1 += 1., 2., 4., 2.;
    cout << "Series1: " << series1 << endl;

    const int size = 7;
    float tab[size] = { 3.,3.,3.,4.,5.,1.,0. };
    const TSeries series2(tab, size);
    cout << "Series2: " << series2 << endl << endl;


    TSeries series3 = series1 + series2;
    cout << "Series3: " << series3 << endl << endl;

    series1 += 1., 0., 3.;
    series3 = series1 + series2;
    cout << "           " << series1 << endl;
    cout << "          +" << series2 << endl;
    cout << "        ---------------------" << endl;
    cout << "Series3:   " << series3 << endl << endl;

    TSeries series4 = series1(2, 4);
    cout << "Series4: " << series4 << endl;

    return 0;
}

/* output required:
Series1: (1,2,4,2)
Series2: (3,3,3,4,5,1,0)

Size doesn't match!
Series3: ()

(1,2,4,2,1,0,3)
+(3,3,3,4,5,1,0)
---------------------
Series3:   (4,5,7,6,6,1,3)

Series4: (4,2)
*/

输出

Series1: (1,2,4,2)

Series2: (3,3,3,4,5,1,0)


Size doesn't match!
Series3: (1,2,4,2)


           (4,5,7,6,6,1,3)

          +(3,3,3,4,5,1,0)

        ---------------------
Series3:   (4,5,7,6,6,1,3)


Series4: (7,6)

更新:

您的operator+(const TSeries &amp;) 应该看起来像这样:

TSeries operator+(const TSeries & other)
{
    if (this->_size != other._size)
    {
        std::cout << "Size doesn't match!" << std::endl;
        return TSeries(); //Return empty object
    }
    TSeries tmp(*this); //Create copy
    for (int i = 0; i < tmp._size; i++)
    {
        tmp._tab[i] += other._tab[i];
    }
    return tmp;
}

你的operator()(int, int) 是这样的:

TSeries operator()(int position1, int position2)
{
    if (position1 < 0) position1 = 0;
    else if (position1 >= _size) position1 = _size - 1;

    if (position2 < position1) position2 = position1;
    else if (position2 >= _size) position2 = _size - 1;

    return TSeries(_tab + position1, position2 - position1);
}

也许您想在错误情况下抛出异常?

【讨论】:

  • 非常感谢。还有一个问题:你的意思是://TODO: Range-Check?
  • @annakowalska 一般来说,我只是修复了最明显的东西。对于范围检查案例:考虑有一个包含 1 个元素的系列,但您想提取 2 到 20 的范围。这将导致解决方案崩溃,因为 _tmp 被访问越界。正确的方法是检查范围是否有效(例如from &gt;= 0 and from &lt;_size and to &gt;= from and to &lt; size)并相应地处理无效值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多