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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
#1

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

09.11.2011, 22:45. Просмотров 716. Ответов 16
Метки нет (Все метки)

Решил я закрепить свои знания по перегрузке операторов и написал свой класс стринга. Естественно я перегрузил оператор извлечения из потока.
Получилось следующие:
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;. Я ж выделяю память под один символ, а потом поток сам расширят его, правильно? Корректно ли это?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.11.2011, 22:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос А можно ли такое делать? (C++):

Можно ли делать шаблоны дружественных функций? - C++
Вот пример того, как я хочу объявить дружественную функцию в классе: friend template <typename T> rational_fraction operator*(T,...

можно ли делать виртуальными перегружаемые операторы? - C++
например так: virtual a& a::operator=(a& b);

Можно ли на C++ делать что то для сайта? - C++
Писать код на С++ , что бы он выполнял какой нить функционал для сайта? Собираюсь начать учить С++, вот думаю о будущем. Или только такое...

Как можно делать скрины в авторежиме? - C++
Как можно делать скрины в авторежиме, что б сохранялись автоматически в jpg в фоновом режиме. Про эмуляцию Print Screen знаю, подскажите в...

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

Такое и в правду можно сделать в консоли? - C++

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

Добавлено через 1 минуту
и в str становится 10,20,30 символов. Как так?
0
oxotnik
1590 / 1067 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
09.11.2011, 22:56 #7
Цитата Сообщение от Zyoma Посмотреть сообщение
Но код работает. Я выделяю под один сивол, ввожу 10,20,30 символов, и он их воспринимает. Почему?
потому что забиваешь невыделенную память, пока везет, что она не нужна никому, потом может пригодиться и будет ой
1
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 22:58  [ТС] #8
А как тогда сделать правильно?
0
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;
}
Ну а главное, я надеюсь вам хватило ума не включать функции взаимодействия между стримами и вашим классом в файлы самого класса?
0
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 23:12  [ТС] #10
len = -1 когда строка пустая, совсем. причем тут нарушение инкапсуляции, если эта функция дружественная? А вам хватит ума написать как надо правильно, а не критиковать вещи совершенно не касающиеся темы?

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

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

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

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

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

Не написать delete ptr; там, где требуется delete[] ptr;
и тп
1
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 23:16  [ТС] #12
конечно же вы не поделитесь своими деццкими разработками. Молоть языком очень прошу не в этой теме. Я обратился за помощью, а не за критикой тролля.
0
ValeryLaptev
Эксперт С++
1041 / 820 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
09.11.2011, 23:18 #13
Zyoma, тут проблема с выделением памяти.
Тебе заранее неизвестно, сколько символов будет введено.
Поэтому в конструкторе твоего класса String нужно застолбить некий минимальный размер, например, 32 символа.
В функции ввода надо вводить посимвольно и считать символы.
Так как возможен ввод более 32 символов, то в кллассе надо предусмотреть приватную функцию resize(), которая должна делать следующее:
затребовать новый динамический массив
скопировать туда уже занятые символы
удалить старый массив
Сменить указатель на новый.
Размер нового динамического массива обычно в два раза больше текущего.
1
Zyoma
10 / 10 / 3
Регистрация: 05.11.2010
Сообщений: 30
09.11.2011, 23:21  [ТС] #14
Вот теперь я понял.
Спасибо огромное.
0
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;

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

Человеку говоришь: у тебя ошибка, мина замедленного действия. А он "аццтань, ты тролль!" Ну тупи дальше тогда.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.11.2011, 23:23
Привет! Вот еще темы с ответами:

Можно ли считать такое решение верным - C++
Напишите программу читающую со стандартного устройства ввода значения типа int и создающую из них вектор. Создайте массив того же размера,...

с++ такое k, для которого можно построить множество - C++
Помогите пожалуйста решить задачу с++!!! Задано семейство множеств букв. Найти такое k, для которого можно построить множество, состоящее...

указатель на void в иерархии классов. можно ли так делать? - C++
здравствуйте! Такое дело: мне нужно написать иерархию классов для работы с таблицей. базовый класс - это просто таблица, а производный...

Хочу понять когда можно делать оператор delete - C++
совсем новичок, а в книге толком не объясняется, помогите понять суть плиз Вот очень простой код: #include <windows.h> class...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
09.11.2011, 23:23
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru