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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перегрузка оератора = Совсем запутался. 
:(
    Опции темы
Martin_8
Дата 16.10.2006, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Здравствуйте, что-то я совсем запутался с перегрузкой =.
При компиляции этого кода возникает шибка 'operator =(my_string)' must be a member function. Не могу понять в чём её причина, помогите, пожалуйста, разобраться. Код набирался в билдере. 

Код

#pragma hdrstop
#include <iostream.h>
#include <conio.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

//---------------------------------------------------------------------------
class my_string
{
private:
    //char *str, *str2;
    //int i,l;
public:
    char *str, *str2;
    int i,l;

    my_string(char *);
    ~my_string();
    void print(char *);
    //my_string operator=(my_string A);
    friend my_string operator=(my_string x);
};


my_string::my_string(char *s="\0")
{
    str = new char [strlen(s)+1];
    strcpy(str,s);

    //str2 = new char [strlen(str)+1];
    //str2 = new char [100];
    cout<<"____Initsializatsiya vypolnena____\n";
}

my_string::~my_string ()
{
    //delete str;
    //delete str2;
    cout<<"\nStroka sterta iz pamyati. Rabota zavershena.\n";
}

void my_string::print (char *ss)
{
    cout<<"Ishodnaya stroka do preobrazovania:"<<endl;
    cout<<"-----------------------------------"<<endl;
    puts(ss);
}

/////////my_string my_string::operator=(my_string t)

my_string operator=(my_string x)
{
    my_string z;
    int j=0;
    int k =0;

    //str2 = new char [strlen(str)+1];
    

    cout<<"Kol-vo "<<strlen(str)<<endl;

    for (i=0; i<strlen(str); i++)
    {
        if (*(str+i)==' ')
        {
            k++;
        }
    }
    cout<<"\nK probelov="<<k<<endl;

    if (k<2)
    {
        cout<<"Uslovie ne vypolnyaetsya, v stroke men'she 2-h probelov. Programma zavershaet rabotu!"<<endl;
        abort();
    }

    str2 = new char [100];

    for (i=0; i<strlen(str); i++)
    {
        if (*(str+i)==' ')
        {
            l++;
        }

        if (l==2)
        {
            //*(str2+j)=t.str[i];
            *(z.str+j)=*(x.str+i);  
            j++;
        }
    }
    return(z);
}

#pragma argsused
main(int argc, char* argv[])
{
char sa[200];

    puts("Vvedite stroky:");
    gets(sa);

    my_string A(sa);
    A.print (A.str);
    

    my_string C("");
    C=A;
    C.print (C.str);
}


PM   Вверх
Daevaorn
Дата 16.10.2006, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

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



Martin_8, 
Оператор присваивания должен быть членом класса. Заметь, тоже самое тебе говорити и компилятор.
PM MAIL WWW   Вверх
Martin_8
Дата 16.10.2006, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

Оператор присваивания должен быть членом класса. Заметь, тоже самое тебе говорити и компилятор. 

Так ведь прототип operator = описан в классе. Или я чего-то не понимаю?  smile 
PM   Вверх
Daevaorn
Дата 16.10.2006, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

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



Цитата(Martin_8 @  16.10.2006,  22:53 Найти цитируемый пост)
Так ведь прототип operator = описан в классе. Или я чего-то не понимаю?  

Видимо да.

Цитата(Martin_8 @  16.10.2006,  21:47 Найти цитируемый пост)
 friend my_string operator=(my_string x);

Это не объявление члена класса. Это объявление функции, как друга класса

Цитата(Martin_8 @  16.10.2006,  21:47 Найти цитируемый пост)
my_string operator=(my_string x)

Это не реализация члена класса, хотя бы потому что нет my_string::х
PM MAIL WWW   Вверх
Kuvaldis
Дата 16.10.2006, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

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



Martin_8, 
Вместо
Код

friend my_string operator=(my_string x);

Поставь
Код

my_string& operator=(my_string x);

В реализации метода
Код

my_string& my_string::operator=(my_string x)


P.S. Совет: хорошо разберить со ссылками, константными- неконстантными. Это очень нужно для рационального расходования памяти и передачи параметров в функции. в частности и в методы.
Т.е.
my_string& operator=(my_string x);

Лучше написать
my_string& operator=(const my_string& x);
Зачем нам копировать в стек в локальные параметры х, если можно передать адрес этой переменной? Причем из-за const изменить ее уже нельзя (защита включена)

Это сообщение отредактировал(а) Kuvaldis - 16.10.2006, 22:32


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
Martin_8
Дата 16.10.2006, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Спасибо

Это сообщение отредактировал(а) Martin_8 - 16.10.2006, 22:32
PM   Вверх
Kuvaldis
Дата 16.10.2006, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

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



Martin_8, 
Цитата

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


что-то вроде этого
Код

#pragma hdrstop    
#include <iostream.h>    
#include <conio.h>    
#include <string.h>    
#include <stdio.h>    
#include <stdlib.h>    
//---------------------------------------------------------------------------    
class my_string    
{    
private:    
    //char *str, *str2;    
    //int i,l;    
public:    
    char *str, *str2;    
    int i,l;    
    my_string(char *);    
    ~my_string();    
    void print(char *);
    //my_string operator=(my_string A);
    const my_string& operator = (const my_string& x);
};
my_string::my_string(char *s="\0")    
{    
    str = new char [strlen(s)+1];    
    strcpy(str,s);    
    //str2 = new char [strlen(str)+1];    
    //str2 = new char [100];    
    cout<<"____Initsializatsiya vypolnena____\n";    
}    
my_string::~my_string ()
{
    //delete str;
    //delete str2;
    cout<<"\nStroka sterta iz pamyati. Rabota zavershena.\n";
}
void my_string::print (char *ss)
{
    cout<<"Ishodnaya stroka do preobrazovania:"<<endl;
    cout<<"-----------------------------------"<<endl;
    puts(ss);
}
/////////my_string my_string::operator=(my_string t)
const my_string& my_string::operator = (const my_string& x)
{
    int j=0;
    int k =0;


    cout<<"Kol-vo "<<strlen(str)<<endl;
    for (i=0; i<strlen(str); i++)
    {
        if (*(str+i)==' ')
        {
            k++;
        }
    }
    cout<<"\nK probelov="<<k<<endl;
    if (k<2)
    {
        cout<<"Uslovie ne vypolnyaetsya, v stroke men'she 2-h probelov. Programma zavershaet rabotu!"<<endl;
        abort();
    }
    str2 = new char [100];
    for (i=0; i<strlen(str); i++)
    {
        if (*(str+i)==' ')
        {
            l++;
        }
        if (l==2)
        {
            //*(str2+j)=t.str[i];
            *(this->str+j)=*(x.str+i);
            j++;
        }
    }
    return *this;
}

#pragma argsused
main(int argc, char* argv[])
{
char sa[200];
    puts("Vvedite stroky:");
    gets(sa);
    my_string A(sa);
    A.print (A.str);

    my_string C("");    
    C=A;    
    C.print (C.str);    
}


P.S. Почитай толковую литературу. Мой совет: Дейтел: Как программировать на С++

Это сообщение отредактировал(а) Kuvaldis - 16.10.2006, 22:38


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
Martin_8
Дата 16.10.2006, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



to Kuvaldis
Ещё раз спасибо за компетентный ответ
PM   Вверх
niknor
Дата 16.10.2006, 22:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 21.4.2006
Где: РОССИЯ, Набережны е челны

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



А почему при перегрузке одних операторов исп-ся friend, при перегрузке же других &(Ну в смысле в самом классе, аа не как дружественные)?
И хотелось бы уточнить при каких.
Заранее спасибо

PM MAIL   Вверх
Kuvaldis
Дата 16.10.2006, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

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



niknor, 
Большинство операций можно перегружать как при помощи friend, так и через методы класса.
Исключение составляют операторы ввода и вывода (<< и >>).
Например, бинарные операции. Для такой операции важно, чтобы параметр слева был элементом класса.

например, класс string
Код

class String
{
       private:
          char*   str;
       public:
          String operator + (const String& r);
          friend String operator - (const string& l, const String& r);
};


При написании в программе суммы двух строк s1 и s2 
s1 + s2 преобразовывается в s1.operator+(s2).

s1 - s2 преобразовывается в operator - (s1, s2);

cout << s1  - это не cout.operator<<(s1)
вызывается дружественная функция operator<< (cout, s1).
Заметь, слева стоит не объект класса string

Данную возможность friend можно использовать, например, для перегрузки выражения, когда слева стоит не элемент класса
например,
s1 = "abc" + s2;
здесь перегружаем оператор + таким образом
String operator + (char* s, const string& r);
Т.е. чуть большая функциональность получается 



Это сообщение отредактировал(а) Kuvaldis - 16.10.2006, 23:16


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
Martin_8
Дата 17.10.2006, 00:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Kuvaldis, 
Я всё исправил, как Вы написали и все, разумеется, работает. Но не могли бы Вы прояснить один момент.

При вызове метода 
Код
 C.print (C.str)
 вместе с нужной строкой, если после двух пробелов, следующее слово >7 символов, выводится какой-то мусор. (Например, ввожу “abc rtyd mpn” => должен поучить mnp, а получаю что-то вроде mnpă“ǞŅ). Самое интересное, что как я проследил в отладчике строчка 
Код

*(this->str+j)=*(x.str+i);
 отрабатывает корректно и ничего лишнего в str обьекта С не пишет. 
Откуда берётся этот мусор и как это можно побороть ?



Это сообщение отредактировал(а) Martin_8 - 17.10.2006, 00:29
PM   Вверх
Kuvaldis
Дата 17.10.2006, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

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



Martin_8, 
выложи свой исправленный вариант кода


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
EvgenZ
Дата 17.10.2006, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Freedom in me
**


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

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



 посмотри сколько итераций делает цикл при выводе. Похоже на то, что лишнии итерации -> выходишь за пределы массива -> мусор.

Это сообщение отредактировал(а) EvgenZ - 17.10.2006, 09:44


--------------------
<удалено администрацией форума>
PM MAIL   Вверх
niknor
Дата 17.10.2006, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 21.4.2006
Где: РОССИЯ, Набережны е челны

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



Предлагаю выводить в цикле посимвольно, до тех пор пока не начнется "мусор". Хоть и мухлёж но сработать должно
PM MAIL   Вверх
JackYF
Дата 17.10.2006, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



niknor, а как ты определишь - где мусор, а где нет smile 
Kuvaldis, в твоем примере - или не только в твоем:

Смысл в классе my_string печатать какую-то левую строчку?
Что за семантика такая! smile 
Код

C.print (C.str);


Вывод строки по идее должен выглядеть:
Код

C.print();


Естественно, при этом внутри метода должен использоваться член класса str.
То есть строка выводит себя.

А то что же у вас получается: строка может содержать, а выводить другое  smile

Добавлено @ 16:39 
Да, и еще вопрос на засыпку: чем в классе занимается переменная str2? И где она удаляется?  smile 

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

Добавлено @ 16:40 
Цитата(JackYF @  17.10.2006,  16:33 Найти цитируемый пост)
строка может содержать,

Я имел в виду "Строка может содержать ОДНО, а выводить другое".



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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