Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.95/22: Рейтинг темы: голосов - 22, средняя оценка - 4.95
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
1

Передача по ссылке

01.08.2019, 12:45. Показов 4012. Ответов 31

Author24 — интернет-сервис помощи студентам
Задание №8 из книги "Объектно-ориентированное программирование в С++", 4-е издание, Роберт Лафоре, 2004г.
В некоторых компьютерных языках, таких, как Visual Basic, есть операции, с помощью которых можно выделить
часть строки и присвоить её другой строке. (В стандартном классе string предложены различные подходы.)
Используя наследование, добавьте такую возможность в класс Pstring из упражнения 2. В новом производном
классе Pstring2 разместите три новых функции: left(), mid() и right().

C++
1
2
3
4
5
6
s2.lef( s1, n )    // в строку s2 помещаются n самых левых
           // символов строки s1
s2.mid( s1, s, n ) // в строку s2 помещаются n символов из 
                   // строки, начиная с символа номер s
s2.right( s1, n )  // в строку s2 помещаются n самых правых
           // символов строки s1
Вы можете использовать цикл for для копирования символ за символом подходящих частей строки s1 во
временный объект класса Pstring2, который затем их возвратит. Для получения лучшего результата используйте
в этих функциях возврат по ссылке, чтобы они могли быть использованы с левой стороны знака "равно" для
изменения существующей строки.

Мой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// task8.1.cpp
// date: Thu 04 Jul 2019 08:36:36 PM EEST
// source: page 409 from Lafore handbook, part 9
#include <iostream>
#include <string.h> // for "str*" functions
using namespace std;
////////////////////
enum { SZ = 80 };
class String
{
protected:    
    char str [ SZ ];
public:
    String()
    { str[ 0 ] = '\x0'; }
    String( char s [] )
    { strcpy( str, s ); }
    void display() const
    { cout << str; }
    operator char*()
    { return str; }
};
////////////////////
class Pstring : public String
{
public:
    Pstring(): String()
    { }
        Pstring( const char st [] )
        {
            if( strlen(st) < SZ ){
               // String::String( st );
                strcpy( str, st );
            }
            else{
                for(size_t i = 0; i < SZ-2; i++ ){
                    str[i] = st[i];
                    str[ SZ-1 ] == '\0';
                }
            }
        }
};
//////////////////////
class Pstring2 : public Pstring
{
    private:
    public:
        Pstring2(): Pstring()
        { }
        Pstring2( const char st []): Pstring(st)
        { }
        char*  left( Pstring2 sourceString, size_t number)
        {
            size_t begin = strlen(str);
        // check if size of copying string correspond to 
        // free place in old string
            if( SZ - 2 - begin > number){
        // then copy
                for(size_t i=0; i < number; begin++, i++){
                    str[begin] = sourceString.str[i];
                }
                str[begin+number] == '\0';
            }else{
                cout << "\n Your string "
                     << "does not tuck on "
                     << "initial string."
                     << "\nError!\n";
            }
            return str;
        }
        char* mid(Pstring2 obj, size_t beg, size_t number)
        {
            size_t begin = strlen(str);
            if(SZ - 1 - begin > number){
                for(size_t i = begin, j = beg; i < number; i++, j++){
                    str[i] = obj.str[j];
                }
                str[number] = '\0';
            }
            else{
                cout << "\n Your string "
                     << "does not tuck on "
                     << "initial string."
                     << "\nError!\n";
            }
            return str;
        }
        char* right(Pstring2 obj, size_t num)
        {
            size_t tmpSize = strlen(obj.str);
            size_t begin = strlen(str);
            size_t theEnd = begin+num;
            size_t start = tmpSize - 1 - num;
            if( SZ - 2 - begin > num){
                for(begin, start; begin < theEnd; begin++, start++){
                    str[begin] = obj.str[start];
                    tmpSize--;
                }
                str[begin+num] == '\0';
            }else{
                cout << "\n Your string "
                     << "does not tuck on "
                     << "initial string."
                     << "\nError!\n";
            }
 
            return str;
        }
        void clear()
        {
            for(size_t i = 0; i < SZ; i++){
                str[i] = '\0';
            }
        }
        size_t getStrSize()
        {
            return strlen(str);
        }
};
//////////////////////
int main()
{
    Pstring ps1("New constructorFrom inheritance class will copy to string SZ-1 characters onlyBut this is not a rule.");
    Pstring obj1("There is a very long string which must be "
"copied to the char array. And then suddenly arise a buffer overflow "
"error.");
    Pstring obj2("Kurz Sentenzen (de).");
     
    cout << endl;
    //////////////////
    Pstring2 obj3("This object of class Pstring2 demonstrate us a long string.");
    Pstring2 obj4("Not so long string.");
    Pstring2 obj6("Object6 very VEry VERy VERY long string could not tuck on initial string and you will have stack overflow if you will try to copy it there...");
 
    //////////////////
    cout << "\nObj3: ";
    obj3.display();
    cout << "\nObj3 size: " <<
    obj3.getStrSize();
    Pstring2 obj5;
    obj5 = obj3.left(obj6, 13);
    cout << "\nobj3.left(obj6, 30) results >> \n";
    obj5.display();
    cout << "\nClearing obj5...\n";
    obj5.clear();
    obj5.display();
    obj3.clear();
    obj3.display();
    cout << '\n';
    obj5 = obj3.mid(obj6, 18, 78);
    obj5.display();
    obj5.clear();
    cout << "\n test right...\n";
    cout << "\nClearing obj5...\n";
    obj5.clear();
    cout << "\nObj5: ";
    obj5.display();
    obj5 = obj4.right(obj6, 15);
    cout << "\nobj4.right(obj6, 15) results >> \n";
    obj5.display();
    cout << "\nClearing obj5...\n";
    obj5.clear();
    obj5 = obj4.right(obj6, 65);
    // test functions on the left side of "=" sign
    cout << "\ntest functions on the left side of \"=\" sign\n";
    obj5.clear();
/*    % g++ task8.1.cpp -o task8.1.exe 
        task8.1.cpp: In function ‘int main()’:
        task8.1.cpp:169:28: error: lvalue required as left operand of assignment
            obj5.right(obj6, 30) = obj4; // does not compile, want lvalue
    */
//    obj5.right(obj6, 30) = obj4; // does not compile, want lvalue
    obj5.display();
 
    return 0;
}
Повторно прочитал задание и теперь у меня появились сомнения, что мой код соответствует заданию.
Если делать через временный объект:

C++
1
2
3
4
5
6
7
8
9
10
11
...
Pstring2& left(Pstring2 obj, int num)
{
        Pstring2 tmp;
        tmp.str = str;
        ...
        for(size_t i=0; i < number; begin++, i++){
                    tmp.str[begin] = sourceString.str[i];
        ...
        return tmp;
}
То после выхода из функции left() по ссылке будет возвращать мусор. В моем же коде не используется
временный объект. И эти функции я не могу использовать слева от знака равно "=". Можно еще создать
глобальный объект класса Pstring2. Тогда будет работать передача по ссылке, можно использовать
слева от знака равно, но глобальный объект != временный объект.
Заранее спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.08.2019, 12:45
Ответы с готовыми решениями:

Передача по ссылке
С помощью функции rand() округлить значение double и передать его по ссылке.

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

Передача по ссылке
Здравствуйте. 1.typedef struct { MATRIXX_LENTA&lt;double&gt;* MATR; //Ленточная матрица }...

Передача массива по ссылке
Как правильно передавать двумерный статический массив в мои функции? #include &lt;iostream&gt; #include...

31
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
01.08.2019, 16:03 21
Лучший ответ Сообщение было отмечено НовыйПетрович как решение

Решение

Author24 — интернет-сервис помощи студентам
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Нигде до этого задания в книге автор не объясняет указатели *this -> мы такое не изучали... Поэтому вопрос
Тогда вот так
C++
1
Pstring &left(Pstring &s,  ......) {.....; return s;}
Других способов нет
1
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 16:17  [ТС] 22
Походу это будет лучший вариант. Мой код нельзя использовать слева от знака равно.
С этим разобрались.
Тогда какую другую книгу посоветуете? Имеет ли смысл бросать эту или сделать это задание как вы посоветовали и идти дальше. Все-таки здесь 9 глав закончил.

Добавлено через 4 минуты
Объясните почему здесь https://en.wikipedia.org/wiki/Most_vexing_parse
TimeKeeper time_keeper(Timer());
Вызывается конструктор чужого, никак не связанного класса?
0
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
01.08.2019, 16:22 23
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
TimeKeeper time_keeper(Timer());
Вызывается конструктор чужого, никак не связанного класса?
Это не конструктор вызывается, это создаётся экземпляр класса Timer и передаётся параметром в конструктор TimeKeeper

Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Имеет ли смысл бросать эту или сделать это задание как вы посоветовали и идти дальше. Все-таки здесь 9 глав закончил.
Чувствую, лучше бросать. Слабовато как-то для 9-ти глав (Хотя, я уже и не помню когда последний раз эти книги читал).
0
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 16:27  [ТС] 24
А есть такие книги, которые вы читали, и можете сказать, что там минимум ошибок?
0
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
01.08.2019, 16:30 25
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
А есть такие книги, которые вы читали, и можете сказать, что там минимум ошибок?
Есть, наверное. Сам я читал их 20 лет назад, поэтому мне сложно что-то посоветовать.
Литература C++
0
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 16:36  [ТС] 26
Мне не сложно взять любую другую. Но именно так я выбрал Лафоре. И сейчас вы мне говорите, что автор учит плохому (это слышу не в первый раз, но во второй - повод задуматься). Где гарантия, что следующий случайно выбранный автор в своей книге допустил меньше ошибок, чем Лафоре?
0
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
01.08.2019, 16:40 27
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Мне не сложно взять любую другую. Но именно так я выбрал Лафоре. И сейчас вы мне говорите, что автор учит плохому (это слышу не в первый раз, но во второй - повод задуматься). Где гарантия, что следующий случайно выбранный автор в своей книге допустил меньше ошибок, чем Лафоре?
Это не я говорил, это DrOffset.

Начни со Страуструпа что-ли.
1
 Аватар для zayats80888
6340 / 3511 / 1427
Регистрация: 07.02.2019
Сообщений: 8,977
01.08.2019, 16:44 28
НовыйПетрович, советую "Базовый курс" Липпмана. Очень грамотно в плане преподнесения информации, все по полочкам разложено. Сам её сейчас читаю, что бы закрепить и дополнить знания, полученные после прочтения
"Programming: Principles and Practice Using C++" Страуструпа и из др. источников. Вторая довольно сумбурная и местами тяжеловата для новичка, но автор не абы кто(хотя все же не преподаватель), тоже очень полезная. Дальше Мейерса планирую читать.
1
Azazel-San
01.08.2019, 16:57
  #29

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Если автор книги (с учетом предоставленных материалов оригинала(!) книги на английском) имел в виду что-то другое, то он просто бредит.
Эт получается у Лафоре плохая книжка?
А ее еще многим советуют..

0
zayats80888
01.08.2019, 17:05
  #30

Не по теме:

Цитата Сообщение от Azazel-San Посмотреть сообщение
Эт получается у Лафоре плохая книжка?
Помимо упомянутого он в том же конструкторе строчкой выше пишет str[j] = '\0'; в то время когда j уже не доступна.

0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
01.08.2019, 21:32 31
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Вы согласны, что это правильно?
Это правильно.

Цитата Сообщение от НовыйПетрович Посмотреть сообщение
огда объясните мне, почему, когда мы добавляем проверку, то "создается временный безымянный объект, который нельзя использовать"? Чем это не возвращение к предыдущему варианту инициализации?
Тем, что вы пишете выражение String(s) не в списке инициализации (не после двоеточия и не до открывающей скобки).
В С++ много контекстно-зависимых семантик. Поэтому выражениеString(s) может иметь совершенно разный смысл в зависимости от того, где вы его напишете и чем при этом будут являться String и s.

Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Все запустилось, но никакого текста нет.
Именно так. Текста нет. Потому что нужная инициализация базового класса не была запущена.

Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Я бы хотел посмотреть как удаляется этот объект.
Можете объявить деструктор и поставить там точку останова.
Я также хочу заметить, что в данном случае, из-за most vexing parse объект будет не безымянный, а именованный. String(s); в данном контексте полностью эквивалентно String s;, правда на неправильность происходящего это не влияет.

Добавлено через 1 минуту
Цитата Сообщение от Azazel-San Посмотреть сообщение
Эт получается у Лафоре плохая книжка?
А ее еще многим советуют..
Да, плохая. На форуме есть по крайней мере еще 4 разных темы, где выяснилось, что в книге подается откровенная дезинформация.

Добавлено через 1 минуту
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Мне не сложно взять любую другую.
Здесь есть целая прикрепленная тема. Выберите там, что понравится. Липпман - отличный вариант.

Добавлено через 3 часа 33 минуты
НовыйПетрович, вообще странно читать от вас удивление по поводу этого, когда вы уже с таким сталкивались:
Точка с запятой после структуры, перечисления, класса
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
02.08.2019, 14:21 32
НовыйПетрович, очень мутно, написано. Я бы (без проверок и пр.) что-то такое наваял:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <string.h>
using namespace std;
 
enum { SZ = 80 };
class String
{
protected:
    char str [ SZ ];
public:
    String()
    { str[ 0 ] = '\x0'; }
    String( char s [] )
    { strcpy( str, s ); }
 
    void display() const
    { cout << str; }
    operator char*()
    { return str; }
};
class Pstring : public String
{
  public:
Pstring()
:String()
{}
Pstring(char *s)
:String(s)
{}
Pstring(const Pstring &rhs)
{strcpy( str, rhs.str);}
 
Pstring &left(const Pstring &rhs, int n)
{
    Pstring tmp(rhs);
    tmp.str[n]='\0';
    strcat(tmp.str, str);
swap(*this, tmp);
return *this;
}
};
 
using namespace std;
 
int main()
{
   Pstring ptarg("world!"), source("Hello friend");
   ptarg.left(source, 6).left(source, 6);
   ptarg.display();
 
    return 0;
}
0
02.08.2019, 14:21
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.08.2019, 14:21
Помогаю со студенческими работами здесь

Передача объекта по ссылке
В книге Шилдта есть задание: #include &lt;iostream&gt; #include &lt;cstring&gt; #include &lt;cstdlib&gt; ...

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

Передача объекта по ссылке
Не работает передача константы по ссылке. Ошибка: &quot;error: passing ‘const std::allocator&lt;int&gt;’ as...

Передача параметра по ссылке
Здравствуйте! Подскажите пожалуйста! Делаю пример из книги: #include &lt;iostream&gt; #include...


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

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
Новые блоги и статьи
Элементы алгоритмизации
hw_wired 28.01.2025
Основы алгоритмизации В современном мире алгоритмы играют фундаментальную роль в развитии информационных технологий и программирования. Понимание основ алгоритмизации является ключевым элементом в. . .
Человек и информация
hw_wired 28.01.2025
Введение: роль информации в познании мира В современном мире информация играет фундаментальную роль в процессе познания окружающей действительности. Она представляет собой совокупность сведений об. . .
Компьютер и информация
hw_wired 28.01.2025
Эволюция вычислительных машин История развития вычислительной техники начинается задолго до появления первых электронных устройств. Человечество всегда стремилось упростить процесс вычислений и. . .
Информационные технологии
hw_wired 28.01.2025
Введение в современные технологии работы с информацией В современном мире информационные технологии стали неотъемлемой частью практически всех сфер человеческой деятельности. Они существенно. . .
Информация вокруг нас
hw_wired 28.01.2025
Основные понятия информации В современном мире понятие информации является фундаментальным и охватывает практически все сферы человеческой деятельности. Информация представляет собой совокупность. . .
Компьютер для начинающих
hw_wired 28.01.2025
Введение в мир компьютерных технологий В современном мире информация стала одним из важнейших ресурсов человечества, определяющим развитие общества и технологий. Наша жизнь неразрывно связана с. . .
[golang] 189. Rotate Array
alhaos 28.01.2025
Повороты рукоятки, целочисленный слайс нужно сдвинуть на целое положительное число. Мне очень нравится решение на GO / / https:/ / leetcode. com/ studyplan/ top-interview-150/ package topInterview . . .
КуМир: решение задач на матрицы
bytestream 28.01.2025
КуМир представляет собой среду для обучения программированию, которая включает в себя мощные инструменты для работы с матрицами. Матрица в программировании - это двумерный массив, состоящий из. . .
КуМир: решение задач на строки
bytestream 28.01.2025
В системе программирования КуМир работа со строковыми данными является одним из важнейших аспектов создания программ. Строки представляют собой последовательности символов, заключенные в кавычки,. . .
КуМир: решение геометрических задач
bytestream 28.01.2025
Программирование геометрических задач в среде КуМир становится всё более актуальным в обучении школьников и студентов. КуМир — это разработанная в России обучающая программная среда, предназначенная. . .
КуМир, исполнитель Водолей: Задачи и решения
bytestream 28.01.2025
КуМир — это образовательная среда для обучения программированию. Она предлагает пользователям разнообразные инструменты для разработки и отладки программ, что особенно ценно для студентов и. . .
КуМир, исполнитель Чертежник: Решение задач
bytestream 28.01.2025
КуМир (Комплект Учебных МИРов) представляет собой образовательную среду для обучения основам программирования и алгоритмизации. Исполнитель Чертежник работает на координатной плоскости, где может. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru