Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.08.2009, 15:21   #11
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Цитата:
Сообщение от Ok-ei Посмотреть сообщение
Спасибо за объяснение...
Только при вызове ++S, программа в UniSchet& UniSchet:: operator++() не заходит... Что не так?
Как это не заходит? Компилируется, код работает, а в этот метод не заходит? Странновато как-то.
Цитата:
Сообщение от Ok-ei Посмотреть сообщение
И еще вопрос: а как написать это
Создайте конструктор копии: UniSchet(const UniSchet &obj);
и в операторе что-то в этом роде:
Код:
UniSchet UniSchet::operator++(int) // Возвращать по значению уже надо
{
  UniSchet res(*this); // Создаём копию текущего объекта
  ++this; // префиксный инкремент, чтобы измежать дублирования кода
  return res; // возвращаем копию копии)
Может быть не самый оптимальный вариант, но достаточно легко реализовывать. Зато понятно сразу, почему рекомендуется везьде префиксный инкремент/декремент использовать
pu4koff вне форума Ответить с цитированием
Старый 17.08.2009, 15:49   #12
Ok-ei
Пользователь
 
Регистрация: 29.03.2009
Сообщений: 22
По умолчанию

Спасибо, стало понятнее...

Цитата:
Сообщение от pu4koff Посмотреть сообщение
Как это не заходит? Компилируется, код работает, а в этот метод не заходит? Странновато как-то.
Компелируется, но при попытке вызвать этот метод программа вылетает.... Что может быть не так?
Ok-ei вне форума Ответить с цитированием
Старый 17.08.2009, 16:35   #13
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Цитата:
Сообщение от Ok-ei Посмотреть сообщение
Компелируется, но при попытке вызвать этот метод программа вылетает.... Что может быть не так?
С указателями ничего не намудрили в конструкторе копии? Может там одно и то же 2 раза удаляется в деструкторе или еще чего... Код конструктора копии в общем показывайте и текст ошибки с которой вылетает
pu4koff вне форума Ответить с цитированием
Старый 17.08.2009, 17:01   #14
Ok-ei
Пользователь
 
Регистрация: 29.03.2009
Сообщений: 22
По умолчанию

Код:
class Schetchik
{ public:
    int a;   // номер цифры в массиве, которая в данный момент выбрана
    int n;  // количество цифр в типе
    char *A; // массив цифр типа
    Schetchik(int m, char *B, char b);
    ~Schetchik();
    char val(); // возвращает значение счетчика
};

 Schetchik::Schetchik(int m, char *B, char b)
    {bool f=0;
     if (m<2)
        ShowMessage("Ошибка: слишком мало цифр в типе. Счетчик создать не удалось.");
     else
        {for (int i=0; i<m; i++)
            for (int j=i+1; j<m; j++)
               if (B[i]==B[j])
                  {ShowMessage("Ошбка: значения цифр в типе совпадают. Счетчик создать не удалось.");
                   f=1;
                  }
         if (f==0)
            {int i=0;
             while ((B[i]!=b)&&(i<m))
                i++;
             if (i>m)
                ShowMessage("Ошбка: значения счетчика не совпадает с типом цифр. Счетчик создать не удалось.");
             else
                {a=i;
                 n=m;
                 A= new char[n];
                 for (int k=0; k<n; k++)
                    A[k]=B[k];
                };
            };
        };
    };

  Schetchik::~Schetchik()
    { delete [] A;
    };

 char Schetchik::val()
    { return A[a];
    };
Код:
class UniSchet
{private:
    char *B;
 public:
    Schetchik **S;
    int m; //разрядность
    UniSchet(int k, int *n, char **A, char *a);
    UniSchet(const UniSchet &Obj); // коструктор копии счетчика
    ~UniSchet();
    char* val(); // возвращает значение счетчика
    UniSchet& operator ++ (); 
    UniSchet operator ++ (int); 
    
};

 UniSchet::UniSchet(int k, int *n, char **A, char *a)
   { if (k>0)
       {m=k;
        S=new Schetchik*[m];
        for(int i=0; i<m; i++)
           S[i]=new Schetchik(n[i], A[i], a[i]);
        B=new char [m+1];
        B[m]='\0';
       }
     else
        ShowMessage("Слишком маленькая разрядность. Счетчик создать не удалось");
   };

 
 UniSchet::UniSchet(const UniSchet &Obj)
   {m=Obj.m;
    S=Obj.S;
    B=Obj.B;
   };

 UniSchet::~UniSchet()
   { for (int i=0; i<m; i++)
        delete [] S[i];
     delete [] S;
     delete [] B;
   };

 char*  UniSchet::val()
    {for (int i=0; i<m; i++)
         B[m-i-1]=S[i]->val();
     return B;
    };

 UniSchet& UniSchet::operator++()
    { int i=0;
      bool f=0;
      while ((i<m)&&(f==0))
         if ((S[i]->a)<(S[i]->n-1))
            {f=1;
             S[i]->a++;
            }
         else
            i++;
      if (f==0)
        ShowMessage("Счетчик заполнен. Значение счетчика увеличить не удалось");
      else
         for (int j=0; j<i; j++)
            S[j]->a=0;
      return *this;

    };

 UniSchet UniSchet::operator++(int)
   { UniSchet res(*this);
     ++this;
     return res;
   };
С постфиксным инкрементом даже не компелируется:
[C++ Error] UniSchet.h(101): E2025 Assignment to 'this' not allowed, use X:: operator new instead
Ok-ei вне форума Ответить с цитированием
Старый 17.08.2009, 17:22   #15
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Поправочка: ++(*this); забыл я что-то, что this - это указатель.
Конструктор копии неправильный. B и S нельзя тупо копировать из obj, потому как получается, что 2 объекта уже будут хранить указатели на одни и те же области данных и в деструкторе одно и то же уничтожать.
Попробуй как-то так:
Код:
Schetchik::Schetchik(const Schetchik &obj)
{
  a = obj.a;
  n = obj.n;
  A = new char[n];
  for (int k = 0; k < n; ++k)
    A[k] = obj.A[k];
}

UniSchet::UniSchet(const UniSchet &obj)
{
  m=Obj.m;
  S=new Schetchik*[m];
  for (int i = 0; i < m; ++m)
    S[i]=new Schetchik(*obj.S[i]);
  B=new char [m+1];
  B[m]='\0';  
};
Писал тут, так что мог где-нибудь оплошать
pu4koff вне форума Ответить с цитированием
Старый 17.08.2009, 17:41   #16
Ok-ei
Пользователь
 
Регистрация: 29.03.2009
Сообщений: 22
По умолчанию

Скомпелировался....
Вылетает при работе:
Debugger exception notification:
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00402554 in module ‘Project1.exe’. Read of address 00000001 '.Process stopped. Use Step or Run to continue.
Ok-ei вне форума Ответить с цитированием
Старый 17.08.2009, 17:57   #17
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Ну пошагово поттлаживайте на какой именно операции вылетает. Мне просто лень это всё собирать в проект и тестить. Где-то косяк с указателями полюбому. Точки останова поставьте в конструкторах копии и инкрементах и посмотрите на какой именно строке какого метода вылетает ошибка.
pu4koff вне форума Ответить с цитированием
Старый 17.08.2009, 19:02   #18
Ok-ei
Пользователь
 
Регистрация: 29.03.2009
Сообщений: 22
По умолчанию

Есть ощущение, что я просто не правильно вызов этих методов пишу:

Код:
UniSchet *S;
char **B;
char C[]={'a', '4', 's'};
int D[]={2,5,3};
B= new char *[3];
B[0]= new char[2];
B[1]= new char[5];
B[2]= new char[3];
B[0][0]='a';
B[0][1]='-';
B[1][0]='*';
B[1][1]='k';
B[1][2]='4';
B[1][3]='a';
B[1][4]='0';
B[2][0]='8';
B[2][1]='q';
B[2][2]='s';

S=new UniSchet(3,D,B,C);
Сам счетчик нормально создается. А вот
Код:
++S
не работает... что не так?
Ok-ei вне форума Ответить с цитированием
Старый 17.08.2009, 19:09   #19
Ok-ei
Пользователь
 
Регистрация: 29.03.2009
Сообщений: 22
По умолчанию

Код:
 ++*S
Вот так работает...
Ok-ei вне форума Ответить с цитированием
Старый 17.08.2009, 19:21   #20
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Ну всё правильно. Ошибка такая же, что и я в постинкременте допустил сначала. ++S - это инкремент указателя. Правильно именно ++*S в данном случае. Ну или UniSchet создавайте на стеке, а не в куче:
Код:
...
UniSchet S(3,D,B,C);
++S;
pu4koff вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите найти ошибку! frantic150 Microsoft Office Excel 0 26.06.2009 18:23
Помогите найти ошибку! Студентка@ Помощь студентам 3 21.05.2008 14:21
Помогите найти ошибку KnDmPetr Паскаль, Turbo Pascal, PascalABC.NET 1 11.04.2008 15:48