оператор перегрузки + (C ++) - PullRequest
0 голосов
/ 30 августа 2010

Эй, я работаю над перегрузкой +, но когда я пытаюсь сделать простой вызов, такой как

статистика а, б, в;

a = b + c;

Когда я делаю вышеупомянутый вызов, он падает. и если я делаю перегрузку =, он просто возвращает ноль. вот часть моего кода. Спасибо за помощь, ребята !!!

FYI next_number (double value), увеличивает динамический массив на 1 и помещает это значение в конец массива.

statistician  operator+(const statistician& left, const statistician& right) 
{
    statistician temp;

    if(left.m_iArraySize == 0)
    {
        return right;
    }
    else if(right.m_iArraySize == 0)
    {
        return left;
    }
    else
    {
        statistician temp;

        for(int i =0; i< left.m_iArraySize; i++)
        {
            temp.next_number(left.m_dSeqArray[i]);
        }

        for(int i =0; i< right.m_iArraySize; i++)
        {
            temp.next_number(right.m_dSeqArray[i]);
        }
        return temp;
    }

} 

Реализация класса

#include "Statistician.h"
#include <iostream>
using namespace std;


namespace main_savitch_2C
{

statistician::statistician()
{
    m_iArraySize=0;
    m_dSeqArray = new double[1]; // Preset our list to 1 items
    m_dSeqArray[0] = 0; 

}



statistician::~statistician()
{    
    delete[] m_dSeqArray;
    m_iArraySize=0;

}

statistician::statistician(const statistician &s)
{
    m_iArraySize=0;
    m_dSeqArray = new double[1]; // Preset our list to 1 items  
    m_dSeqArray[0] = 0;

}  

int statistician::ChangeArraySize(int iArraySize)
{


    double *iTempArray;
    iTempArray = new double[m_iArraySize];

    //Assert Data   
    assert(iArraySize >-1);
    // Copy the info of the array into a temp array

    for(int i = 0; i < m_iArraySize-1; i++)
    {

        iTempArray[i] = m_dSeqArray[i];
    }
//    iTempArray = m_dSeqArray;
    // delete the array 

    delete[] m_dSeqArray;



    m_dSeqArray = new double[iArraySize];



    // Copy the info of the temp array  back into the orginal array variable

    for(int i = 0; i < m_iArraySize; i++)
    {

        m_dSeqArray[i] = iTempArray[i];
    }
    m_dSeqArray[iArraySize-1]=0;

    // Free our TempArray
    delete[] iTempArray;

    return 0;
}

//length
int statistician::length() const
{
    if(m_iArraySize == 0) {return 0;}

    return m_iArraySize;
}

//sum()
double statistician::sum() const
{
   if(m_iArraySize == 0) {return 0;}     

    long double dSum=0; 
    for(int i = 0; i < m_iArraySize; i++)
    {
        dSum = dSum + m_dSeqArray[i];
    }
    return dSum;
}

//mean()
double statistician::mean() const
{ 
    if(m_iArraySize == 0) {return 0;}

    double dSum,dMean; 
    int iCounter; 

    dSum=0;
    dMean=0;
    iCounter=0;

    for(int i = 0; i < m_iArraySize; i++)
    {

        dSum = dSum + m_dSeqArray[i];
        iCounter++;
    }

    // Check for Dividing by zero 
    if(dSum == 0)
    {
        dMean = 0; 
    }
    else 
    {
        dMean = dSum/iCounter; 
    }
    return dMean;

}

//reset()
int statistician::reset()
{

    delete[] m_dSeqArray;


    m_iArraySize = 0;

    m_dSeqArray = new double[1];
    m_dSeqArray[0] = 0;

    return 0;
}

//next_number(i)
int statistician::next_number(double iValue)
{
    // Ensure that size of the array has not somehow become negative 


    m_iArraySize++;

    if(m_iArraySize > 1)
    {

        ChangeArraySize(m_iArraySize);
        m_dSeqArray[m_iArraySize-1] = iValue;



    }
    else 
    {

        m_dSeqArray[m_iArraySize-1] = iValue;


    }



    return 0;
}

//next_number(int iValue)
int statistician::next_number(int iValue)
{


    m_iArraySize++;

    if(m_iArraySize > 1)
    {

        ChangeArraySize(m_iArraySize);
        m_dSeqArray[m_iArraySize-1] = iValue;



    }
    else 
    {

        m_dSeqArray[m_iArraySize-1] = iValue;


    }

    return 0;
}

//next_number(char iValue) in case a character is passed 
int statistician::next_number(char iValue)
{
     cout << "Invalid value passed to next_number!" <<endl;

    return 0;
}

//Minimum


double statistician::minimum() const
{
 if(m_iArraySize == 0) {return 0;}

    double dMinimum = m_dSeqArray[0];
    for(int i = 0; i < m_iArraySize; i++)
    {

        if(m_dSeqArray[i] < dMinimum)
        {
            dMinimum = m_dSeqArray[i];

        }     
    }
    return dMinimum;
}

//Maximum
double statistician::maximum() const
{
    if(m_iArraySize == 0) {return 0;}

    double dMaximum = m_dSeqArray[0];
    for(int i = 0; i < m_iArraySize; i++)
    {

        if(m_dSeqArray[i] > dMaximum)
        {
            dMaximum = m_dSeqArray[i];

        }     
    }
    return dMaximum;

}

//Operator Overloading
/*
statistician statistician::operator=( statistician& left)
{
    cout << left.sum();
    cout << left.length();
    cout << this->sum();

    if(this != &left)
    {
        this->reset();
        for (int i =0; i < left.m_iArraySize; i++)
        {
            this->next_number(left.m_dSeqArray[i]);
            cout<<this->next_number(left.m_dSeqArray[i]) <<endl;
            cout<<left.next_number(left.m_dSeqArray[i]) <<endl;
        }
    }
    return *this;


} */
statistician  operator+(const statistician& left, const statistician& right)
{
    statistician temp;

    if(left.m_iArraySize == 0)
    {
        return right;
    }
    else if(right.m_iArraySize == 0)
    {
        return left;
    }
    else
    {
        statistician temp;

        for(int i =0; i< left.m_iArraySize; i++)
        {
            temp.next_number(left.m_dSeqArray[i]);
        }

        for(int i =0; i< right.m_iArraySize; i++)
        {
            temp.next_number(right.m_dSeqArray[i]);
        }
        return temp;
    }

} 


bool  operator==( const statistician& left,const   statistician& right)
{ 
    cout << "L length = : "<<left.length() <<" R Length: "<< right.length()<<endl;
    if(left.length() != right.length()) { return false; }

        cout << "L minimum = : "<<left.minimum() <<" R minimum: "<< right.minimum()<<endl;
    if(left.minimum() != right.minimum()) { return false; }

    cout << "L maximum = : "<<left.maximum() <<" R maximum: "<< right.maximum()<<endl;
    if(left.maximum() != right.maximum()) { return false; }

    cout << "L sum = : "<<left.sum() <<" R sum: "<< right.sum()<<endl;
    if(left.sum() != right.sum() ) {return false; }

    cout << "L mean = : "<<left.mean() <<" R mean: "<< right.mean()<<endl;
    if(left.mean() != right.mean() ) {return false; }  






    return true;

}


} // End of Namespace 

и .h ....

#ifndef StatClass
#define StatClass
#include <cassert>


namespace main_savitch_2C
{



class  statistician     //With copy constructor
{
  public:

    // Constructor
    statistician();


    //Deconstructor 
    ~statistician();

    //Copy constructor      
    statistician(const statistician &s);

    //length
    int length() const;

    //sum()
    double sum() const;

    //mean()
    double mean() const;

    //reset()
    int reset();

    //next_number(i)
    int next_number(double iValue);
    int next_number(int iValue);
    int next_number(char iValue);

    //Minimum

    double minimum() const;

    //Maximum
    double maximum() const;


    //Operator Overloading
    //statistician operator=(statistician& left);
    friend statistician operator+(const statistician& left, const statistician& right);
    friend bool operator==(const statistician& left, const statistician& right); 





  private:
    // Private Variables
    double *m_dSeqArray;
    int m_iArraySize;

    // Private Functions
    int ChangeArraySize(int iArraySize);





};

};  
#endif

Ответы [ 3 ]

2 голосов
/ 30 августа 2010

Если вы не определили оператор присваивания (operator=), то компилятор предоставляет версию по умолчанию, которая делает поверхностное копирование, то есть копирует указатель m_dSeqArray,но не то, на что оно указывает.Поэтому, когда вы используете его, вы получаете два указателя, указывающих на одно и то же.Когда два статистика выходят из области видимости, каждый вызывает деструктор, который дважды пытается удалить массив, BOOM!

Ваша версия оператора присваивания дважды копирует каждый элемент:

this->next_number(left.m_dSeqArray[i]);
cout<<this->next_number(left.m_dSeqArray[i]) <<endl;

Таким образом, результирующий статистик должен выглядеть странно, но не быть пустым (если назначенный статистик не был пустым, как в вашем примере).

1 голос
/ 30 августа 2010

Во-первых, канонический operator+ должен быть реализован в терминах operator+=, и именно в этом операторе вы должны написать свою логику.

Во-вторых, statistician конструктор копирования ничего не копирует, он просто создает значение по умолчанию statistician.Поскольку operator+ использует конструктор копирования для возвращаемого значения, вы никогда не получите то, что намереваетесь.

В-третьих, statistician::next_number() не делает то, что вы думаете.Вы никогда не увеличите размер внутреннего массива, так что в итоге вы выйдете за пределы.Это приводит к неопределенному поведению, возможно, к краху, когда вы перезаписываете память, принадлежащую другим объектам.

Я не проверил весь код для всех методов, но вы должны обязательно исправить эти три ошибки, прежде чем продолжить.Ну, первый не так важен, но два других просто необходимы.

0 голосов
/ 30 августа 2010

Хотя это и не является прямой причиной сбоя, я не могу не указать на это

Конструктор копирования выглядит как вырезка из конструктора. Это может не так, я верю. Конструктор копирования может быть задействован, так как оператор + включает в себя возврат копии, которая может вызвать конструктор копирования, если она не удалена.

Как вы используете 's' в конструкторе копирования?

statistician::statistician(const statistician &s) 
{ 
    m_iArraySize=0; 
    m_dSeqArray = new double[1]; // Preset our list to 1 items   
    m_dSeqArray[0] = 0; 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...