Форум программистов, компьютерный форум CyberForum.ru

А можно ли такое делать? - C++

Восстановить пароль Регистрация
 
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 22:45     А можно ли такое делать? #1
Решил я закрепить свои знания по перегрузке операторов и написал свой класс стринга. Естественно я перегрузил оператор извлечения из потока.
Получилось следующие:
C++
1
2
3
4
5
6
7
8
std::istream& operator>>(std::istream& ins, String& st)
{
    if (st.len != -1) delete [] st.str;
    st.str = new char;
    ins >> st.str;
    st.len = strlen(st.str);
    return ins;
}
Меня смущает строка st.str = new char;. Я ж выделяю память под один символ, а потом поток сам расширят его, правильно? Корректно ли это?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.11.2011, 22:45     А можно ли такое делать?
Посмотрите здесь:

можно ли изменить имена объектов cin и cout? залесть в хедер (знаю, этого лучше не делать), и изменить обявление обектов? к примеру на chitai и pishi? C++
C++ указатель на void в иерархии классов. можно ли так делать?
C++ можно ли делать виртуальными перегружаемые операторы?
C++ Можно ли на C++ делать что то для сайта?
C++ Такое и в правду можно сделать в консоли?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Net_Wanderer
235 / 208 / 19
Регистрация: 08.06.2011
Сообщений: 467
09.11.2011, 22:47     А можно ли такое делать? #2
Цитата Сообщение от Zyoma Посмотреть сообщение
Я ж выделяю память под один символ, а потом поток сам расширят его, правильно? Корректно ли это?
нет, на оба вопроса
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 22:50  [ТС]     А можно ли такое делать? #3
А подробнее?
Net_Wanderer
235 / 208 / 19
Регистрация: 08.06.2011
Сообщений: 467
09.11.2011, 22:52     А можно ли такое делать? #4
Цитата Сообщение от Zyoma Посмотреть сообщение
А подробнее?
вы выделяете память под один символ, "поток" ничего не расширяет
oxotnik
 Аватар для oxotnik
1584 / 1061 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
09.11.2011, 22:52     А можно ли такое делать? #5
Цитата Сообщение от Zyoma Посмотреть сообщение
поток сам расширят его, правильно
а где это такое написано? откуда поток узнает на какой тип расширять?
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 22:55  [ТС]     А можно ли такое делать? #6
Но код работает. Я выделяю под один сивол, ввожу 10,20,30 символов, и он их воспринимает. Почему?

Добавлено через 1 минуту
и в str становится 10,20,30 символов. Как так?
oxotnik
 Аватар для oxotnik
1584 / 1061 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
09.11.2011, 22:56     А можно ли такое делать? #7
Цитата Сообщение от Zyoma Посмотреть сообщение
Но код работает. Я выделяю под один сивол, ввожу 10,20,30 символов, и он их воспринимает. Почему?
потому что забиваешь невыделенную память, пока везет, что она не нужна никому, потом может пригодиться и будет ой
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 22:58  [ТС]     А можно ли такое делать? #8
А как тогда сделать правильно?
Bers
Заблокирован
09.11.2011, 23:05     А можно ли такое делать? #9
Честно говоря, я вообще не вижу логики:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
std::istream& operator>>(std::istream& ins, String& st)
{
        if (st.len != -1)   //как длина вообще может быть отрицательным числом?
        {   
             delete [] st.str;    //нарушение инкапсуляции. 
                                       //Доступ к данным в обход интерфейса объекта
         }
         st.str = new char;   //вернётся указатель на один объект типа чар. 
                 //Если str должен указывать на строку, то это явный фейл
          ins >> st.str;
          st.len = strlen(st.str);
           return ins;
}
Ну а главное, я надеюсь вам хватило ума не включать функции взаимодействия между стримами и вашим классом в файлы самого класса?
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 23:12  [ТС]     А можно ли такое делать? #10
len = -1 когда строка пустая, совсем. причем тут нарушение инкапсуляции, если эта функция дружественная? А вам хватит ума написать как надо правильно, а не критиковать вещи совершенно не касающиеся темы?

Добавлено через 4 минуты
str - это указатель на char, причем тут указатель на строку?
Bers
Заблокирован
09.11.2011, 23:14     А можно ли такое делать? #11
Цитата Сообщение от Zyoma Посмотреть сообщение
len = -1 когда строка пустая, совсем. причем тут нарушение инкапсуляции, если эта функция дружественная? А вам хватит ума написать как надо правильно, а не критиковать вещи совершенно не касающиеся темы?
Ну если строка пустая, значит количество символов, которое она содержит рано нуль. Логично?

Мне ума хватит. Я писал когда свой деццкий велосипед строк. Это было первое, что я сделал на с++.

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

Добавлено через 1 минуту
Цитата Сообщение от Zyoma Посмотреть сообщение
str - это указатель на char, причем тут указатель на строку?
Указатель на что? На символ чар? или на массив символов чар?

Сам язык не делает различие между указателем на объект, или на массив объектов. За этим следит программист. Его задача знать что это на самом деле - указатель на объект, или на массив. И соотвественно не встрять на этом.

Не написать delete ptr; там, где требуется delete[] ptr;
и тп
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 23:16  [ТС]     А можно ли такое делать? #12
конечно же вы не поделитесь своими деццкими разработками. Молоть языком очень прошу не в этой теме. Я обратился за помощью, а не за критикой тролля.
ValeryLaptev
Эксперт C++
1004 / 783 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
09.11.2011, 23:18     А можно ли такое делать? #13
Zyoma, тут проблема с выделением памяти.
Тебе заранее неизвестно, сколько символов будет введено.
Поэтому в конструкторе твоего класса String нужно застолбить некий минимальный размер, например, 32 символа.
В функции ввода надо вводить посимвольно и считать символы.
Так как возможен ввод более 32 символов, то в кллассе надо предусмотреть приватную функцию resize(), которая должна делать следующее:
затребовать новый динамический массив
скопировать туда уже занятые символы
удалить старый массив
Сменить указатель на новый.
Размер нового динамического массива обычно в два раза больше текущего.
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 23:21  [ТС]     А можно ли такое делать? #14
Вот теперь я понял.
Спасибо огромное.
Bers
Заблокирован
09.11.2011, 23:23     А можно ли такое делать? #15
Цитата Сообщение от Zyoma Посмотреть сообщение
конечно же вы не поделитесь своими деццкими разработками. Молоть языком очень прошу не в этой теме. Я обратился за помощью, а не за критикой тролля.
Я могу поделиццо своим деццким лесапедом. Мне не жалко. Если конечно, вы меня об этом вежливо попросите.

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

Если вы выделяете память вот так: char ptr = new char;
То удалять её вы сможете только вот так: delete ptr; ptr=0;

Если вы выделяете память вот так: char ptr = new char [MAX];
То удалять её вы сможете только вот так: delete [] ptr; ptr=0;

То есть, правило простое: если выделял память под массив, то и удаляй тоже массив
Если выделял под объект, то и удаляй тоже объект.

Если попутаешь - потом прибежишь на этот форум и будишь спрашивать: почему у меня в рантайме лагает.

Потому что компилятор не различает указатель на массив, от указателя на объект.

А теперь смотри как ты создаёшь:

C++
1
st.str = new char;
и как удаляешь

C++
1
if (st.len != -1) delete [] st.str;

Это называется "порча памяти", и "неизвестное поведение".

Человеку говоришь: у тебя ошибка, мина замедленного действия. А он "аццтань, ты тролль!" Ну тупи дальше тогда.
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 23:28  [ТС]     А можно ли такое делать? #16
Все конечно хорошо, спасибо. Но я читал столько высокомерия в твоих указаниях об ошибках, что стало тошно.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.11.2011, 00:14     А можно ли такое делать?
Еще ссылки по теме:

Хочу передать в функцию несколько разнотипных массивов. Можно так делать? C++
C++ Хочу понять когда можно делать оператор delete
Кто-нибудь может подробно объяснить, что такое allocators, зачем это и что с ними делать? Нигде не нашёл инфы C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Bers
10.11.2011, 00:14     А можно ли такое делать?
  #17

Не по теме:

Цитата Сообщение от Zyoma Посмотреть сообщение
Все конечно хорошо, спасибо. Но я читал столько высокомерия в твоих указаниях об ошибках, что стало тошно.
Вы меня извините пожалуйста. Я совершенно не хотел вас ничем задеть.
Я думал вы для того и выложили код, что бы его покритиковали, и указали на ошибки и изъяны
Я не хотел показаться высокомерным.

Yandex
Объявления
10.11.2011, 00:14     А можно ли такое делать?
Ответ Создать тему
Опции темы

Текущее время: 10:20. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru