Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Класс для работы с дин. массивом, Перегрузка оператора + 
V
    Опции темы
heforma
Дата 16.1.2012, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 9.8.2011

Репутация: нет
Всего: нет



Здравствуйте у меня возникла проблема 
вот код:
Код

#include <iostream>
using namespace std;
class A{
    int *str1;
    int *str2;
    int n1;
    int n2;
private:
    void freeMem(){
        if(str2!=NULL){
            delete []str2;
        }
        if(str1!=NULL){
            delete []str1;
        }
    }
public:
    A(){
        n1=0;
        n2=0;
        str1=NULL;
        str2=NULL;
    }
    A(int n1,int n2){
        this->n1=n1;
        this->n2=n2;

        str1=new int[n1];
        str2=new int[n2];

        str1[0]=0;
        str2[0]=0;
    }
    ~A(){
        freeMem();
    }
    void operator = (A obj){
        n1=obj.n1;
        n2=obj.n2;
        delete []str1;
        delete []str2;
        str1=new int [n1];
        str2=new int [n2];
        for(int i=0;i<n1;i++){
            str1[i]=obj.str1[i];
        }
        for(int i=0;i<n2;i++){
            str2[i]=obj.str2[i];
        }
    }
    A operator + (A obj){
        A temp1(n1+obj.n1,n2+obj.n2);

        for(int i=0,j=-n1;i<temp1.n1;i++,j++){
            if(j<0){
                temp1.str1[i]=str1[i];
            }
            else{
                temp1.str1[i]=obj.str1[j];
            }
        }
            //
        for(int i=0,j=-n2;i<temp1.n2;i++,j++){
            if(j<0){
                temp1.str2[i]=str2[i];
            }
            else{
                temp1.str2[i]=obj.str2[j];
            }
        }
        return temp1;
    }
    void SetStr(int n1,int n2,int *tmp1,int *tmp2){
        this->n1=n1;
        this->n2=n2;
        delete []str2;
        delete []str1;
        str1=new int[n1];
        str2=new int[n2];
        memcpy(str1,tmp1,sizeof(int)*n1);
        memcpy(str2,tmp2,sizeof(int)*n2);
    }
    void Show(){
        for(int i=0;i<n1;i++){
            cout<<str1[i]<<' ';
        }
        cout<<endl;
        for(int i=0;i<n2;i++){
            cout<<str2[i]<<' ';
        }
        cout<<endl;
    }
};
void main(){
    const int s1=5;
    const int s2=7;
    int arr1[s1];
    int arr2[s2];
    for(int i=0;i<s1;i++){
        arr1[i]=i+1;
    }
    for(int i=0;i<s2;i++){
        arr2[i]=i+1;
    }
    A obj1(s1,s2);
    A obj2(s1,s2);
    obj1.SetStr(s1,s1,arr1,arr1);
    obj2.SetStr(s2,s2,arr2,arr2);
    obj1.Show();
    obj2.Show();
    A obj3;
    obj3=obj1+obj2;
    obj3.Show();
}


этот код не работает =( я предполагаю из за того что  для объекта temp1 срабатывает деструктор и в перегруженный оператор = поступает объект с
указателями на пустоту.

вот код исправленный моим преподавателем:

Код

/*
Предположим мне нужно создать класс для работы с 2 динамичискими массивам и нужно перегрузить операторы + и =.
*/

#include <iostream>
using namespace std;
class A{
    int *str1;
    int *str2;
    int n1;
    int n2;

private:

    void freeMem(){
        if(str2 != NULL) {
            delete []str2;
        }
        if(str1 != NULL) {
            delete []str1;
        }
    }

    void newMem(int n1, int n2){
        this->n1=n1;
        this->n2=n2;

        str1=new int[n1];
        str2=new int[n2];
        fillArray(str1,n1,0);
        fillArray(str2,n2,0);
    }

    void fillArray(int arr[],int size,int value){
        for(int i = 0; i < size; i++){
            arr[i] = value;
        }
    }
public:
    A() {
        n1=0;
        n2=0;
        str1=NULL;
        str2=NULL;
    }
    A(int n1,int n2) {
        newMem(n1,n2);
    }
    A(const A& obj) {
        newMem(obj.n1,obj.n2);
        for(int i = 0; i < n1; i++){
            str1[i] = obj.str1[i];
        }
        for(int i = 0; i < n2; i++){
            str2[i] = obj.str2[i];
        }
    }
    ~A(){
        freeMem();
    }
    void operator = (A obj ){
        n1=obj.n1;
        n2=obj.n2;
        delete []str1;
        delete []str2;
        str1=new int [n1];
        str2=new int [n2];
        for(int i=0;i<n1;i++){
            str1[i]=obj.str1[i];
        }
        for(int i=0;i<n2;i++){
            str2[i]=obj.str2[i];
        }
    }
    A operator + (A obj) {
        A temp1(n1+obj.n1,n2+obj.n2);

        for(int i=0,j=-n1;i<temp1.n1;i++,j++){
            if(j<0){
                temp1.str1[i]=str1[i];
            }
            else{
                temp1.str1[i]=obj.str1[j];
            }
        }
            //
        for(int i=0,j=-n2;i<temp1.n2;i++,j++){
            if(j<0){
                temp1.str2[i]=str2[i];
            }
            else{
                temp1.str2[i]=obj.str2[j];
            }
        }
        return temp1;
    }
    void GetStr(int n1,int n2,int *tmp1,int *tmp2) {
        freeMem();
        newMem(n1, n2);
        memcpy(str1,tmp1,sizeof(int)*n1);
        memcpy(str2,tmp2,sizeof(int)*n2);
    }
    void Show() {
        for(int i=0;i<n1;i++){
            cout<<str1[i]<<' ';
        }
        cout<<endl;
        for(int i=0;i<n2;i++){
            cout<<str2[i]<<' ';
        }
        cout<<endl;
    }
    
};
void main(){
    const int s1=5;
    const int s2=7;
    int arr1[s1];
    int arr2[s2];
    for(int i=0;i<s1;i++){
        arr1[i]=i+1;
    }
    for(int i=0;i<s2;i++){
        arr2[i]=i+1;
    }
    A obj1(s1,s2);
    A obj2(s1,s2);
    obj1.GetStr(s1,s1,arr1,arr1);
    obj2.GetStr(s2,s2,arr2,arr2);
    obj1.Show();
    obj2.Show();
    A obj3;
    obj3=obj1+obj2;
    obj3.Show();
}


Я не могу понять почему код преподавателя работает, а мой нет =( ведь деструкторы у нас фактически одинаково отрабатывают (поправьте если не прав)
За ранее благодарю =) 
PM MAIL   Вверх
heforma
Дата 17.1.2012, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 9.8.2011

Репутация: нет
Всего: нет



Проблему решил... у меня не было конструктора копирования. Только я не пойму каким образом он спасает ситуацию... объясните пожалуйста.
PM MAIL   Вверх
borisbn
Дата 17.1.2012, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



т.к. ты делаешь return temp1; то компилятор пытается создать объект, который нужно вернуть из temp1, а т.к. нет конструктора копирования, то он просто делает точную копию объекта. Таким образом у двух объектов указатель str1 указывает на одну и ту же память (с str2, ессно, то же самое). При удалении одного объекта память освобождается, а при удалении второго получается бабах smile
Если упростить ситуацию (без классов), то происходит следующее
Код

char * p1 = new char[ 10 ];
char * p2 = p1;
delete [] p1;
delete [] p2; // <--------



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
heforma
Дата 17.1.2012, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 9.8.2011

Репутация: нет
Всего: нет



Цитата(borisbn @ 17.1.2012,  09:43)
т.к. ты делаешь return temp1; то компилятор пытается создать объект, который нужно вернуть из temp1, а т.к. нет конструктора копирования, то он просто делает точную копию объекта. Таким образом у двух объектов указатель str1 указывает на одну и ту же память (с str2, ессно, то же самое). При удалении одного объекта память освобождается, а при удалении второго получается бабах smile
Если упростить ситуацию (без классов), то происходит следующее
Код

char * p1 = new char[ 10 ];
char * p2 = p1;
delete [] p1;
delete [] p2; // <--------

Спасибо =) теперь понятно =)
PM MAIL   Вверх
xvr
Дата 17.1.2012, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(borisbn @  17.1.2012,  09:43 Найти цитируемый пост)
т.к. ты делаешь return temp1; то компилятор пытается создать объект, который нужно вернуть из temp1,

Кстати, в операторах присваивания и сложения то же самое происходит для входного параметра. Его вообще лучше было описать как const A& - не будет лишних копирований объекта A

PM MAIL   Вверх
spyswamp
Дата 17.1.2012, 16:19 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 349
Регистрация: 18.8.2006

Репутация: 1
Всего: 7



heforma, изучи как правильно записываются формы операторов. У тебя ерунда написана.


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0475 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.