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

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

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

Студворк — интернет-сервис помощи студентам
Задание №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; //Ленточная матрица } DATA_LENTA, *PDATA_LENTA; DWORD WINAPI...

31
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
01.08.2019, 13:14
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Повторно прочитал задание и теперь у меня появились сомнения, что мой код соответствует заданию.
Правильно сомневаешься, не соответствует.
Здесь, наверное надо как-то так (на примере std::string, для простоты)

C++
1
2
3
4
5
6
7
8
9
10
11
12
class Pstring
: public std::string
{
public:
 
    void left(const char *psz, size_t n)
    {
        const auto ln = strlen(psz);
        append(psz, psz + std::min(ln, n));
    }
........................................................
};
0
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 13:23  [ТС]
Написать свой класс String предложил сам автор. Я ничего не выдумал. Поэтому и наследуем от него:
C++
1
2
3
4
5
6
...
////////////////////
class Pstring : public String
{
public:
...
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
01.08.2019, 13:26
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Написать свой класс String предложил сам автор. Я ничего не выдумал. Поэтому и наследуем от него:
Я и не возражаю, просто не хотелось писать лишний код.
Сделай в классе String метод append - добавление строки в конец, и можешь заменть std::string на свой
0
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 13:33  [ТС]
Суть вашего предложения, oleg-m1973, состоит в добавлении строки в конец. Но мой код на данный момент с этим справляется. В этой части я пока не вижу ошибок. А вы?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
01.08.2019, 13:45
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Суть вашего предложения, oleg-m1973, состоит в добавлении строки в конец. Но мой код на данный момент с этим справляется. В этой части я пока не вижу ошибок. А вы?
Ошибки в коде я не смотрел.
Зато вижу, что код для добавления дублируется в каждой функции. Очевидно, что его надо оформить в отдельный метод.
Сравни сколько занимает твоя реализация left и моя

Добавлено через 41 секунду
Суть моего предложения не в добавлении строки - я просто показал правильную реализацию left(), как в задании
0
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,808
01.08.2019, 14:08
Лучший ответ Сообщение было отмечено НовыйПетрович как решение

Решение

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
как в задании
В задании, автор книги просит возвращать объект по ссылке. Это можно сделать, если возвращать *this. Однако в этом же задании он упоминает временный объект (что бы за этим не скрывалось), который по ссылке вернуть нельзя. Это противоречащие друг другу пункты.

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

Судя по выделенному, автор книги вообще не понимает о чем он пишет. И я теперь не удивлюсь, если он действительно предлагает читателю возвращать локальный объект по ссылке.
1
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 14:15  [ТС]
Допустим, oleg-m1973, я согласен с замечанием (хотя в вашей функции не используется цикл for, рекомендуемый автором). Как насчет использования временного объекта и передачи его по ссылке (это более-менее понятно по отдельности, но вместе пока не представляю)?

Добавлено через 4 минуты
DrOffset, я на скрине ясно вижу, что в случае, если строка длиннее SZ (80 символов), тогда Лафоре копирует столько, сколько влезет ( я так делал вначале). А там, где вы выделили красным квадратом, будет выполняться, когда строка полностью влазит.

Дело в том, что указатель this будет в последующих главах, поэтому задачу нужно решить имеющимися средствами.
0
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,808
01.08.2019, 14:18
НовыйПетрович, если брать пример oleg-m1973, то возврат по ссылке может выглядеть вот так и никак иначе:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class Pstring
    : public std::string
{
public:
 
    Pstring & left(const char *psz, size_t n)
    {
        const auto ln = strlen(psz);
        append(psz, psz + std::min(ln, n));
        return *this;
    }
........................................................
};
Никаких временных объектов тут, естественно, нет.
Если автор книги (с учетом предоставленных материалов оригинала(!) книги на английском) имел в виду что-то другое, то он просто бредит.

Добавлено через 1 минуту
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
А там, где вы выделили красным квадратом, будет выполняться, когда строка полностью влазит.
Там, где я выделил, создается временный объект String и тут же уничтожается. Никакой инициализации базового класса не происходит. Вы находитесь под влиянием плохой книги, которая учит вас ошибочным вещам.
1
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 14:25  [ТС]
DrOffset, вы не могли бы объяснить подробнее, почему объект создается и сразу удаляется. Мы будем инициализировать любой объект класса Pstring. Код класса - как на картинке. Для этого вызовется конструктор базового класса и все. В чем тут ошибка. Я не защищаю автора, мне надо понять, где он допускает ошибку.
0
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,808
01.08.2019, 14:34
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
вы не могли бы объяснить подробнее, почему объект создается и сразу удаляется.
Потому что инициализация базового класса возможна только в списке инициализации конструктора (начинается с двоеточия). В вашем коде, это, например, 27 строка. Если вы пишете как на скрине, то это выражение означает создание временного (безымянного) объекта. Его значение можно потом куда-то записать, например (покажу на простых типах)
C++
1
int a = int(10); // int(10) - создает временный объект
но если оставить как на скрине,
C++
1
int(10);
то получится просто бесполезная работа: создали объект, инициализировали и больше с ним ничего не делаем.

Добавлено через 2 минуты
Это азы С++ и не может быть опечаткой, слишком много нужно "опечататься", чтобы такое получилось. Вывод - автор не понимает, что он делает неправильно, ну или его литературные рабы не понимают. В любом случае - это показатель качества книги, а значит и качества ваших знаний после ее прочтения.
0
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 14:42  [ТС]
Ранее в этой книге автор объяснял, что если мы используем конструктор только для инициализации:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class SomeClass
{
private:
    int a;
    float b;
    double c;
public:
    SomeClass()
    {
        a = 0;
        b = 0;
        c = 0;
    }
То эту конструкцию следует заменять инициализацией после двоеточия:

C++
1
2
3
...
SomeClass(): a=0, b=0, c=0
    { }
В данном случае на картинке оригинала учебника я вижу лишь возвращение к предыдущей форме. Я не прав?
0
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,808
01.08.2019, 14:54
А вообще, в данном случае даже временного объекта не будет, а будет объявление переменной типа String с именем s (ибо most vexing parse). А ошибки переобъявления не было только потому, что данное выражение находится в блоке else. И в любом случае делаться будет не то, о чем пишет автор в комментариях.

Добавлено через 1 минуту
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Я не прав?
Нет, не прав. Просто запустите этот пример из скрина и выведите значение str на экран после.

Добавлено через 4 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Просто запустите этот пример из скрина и выведите значение str на экран после.
Вот подобный пример:
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
#include <iostream>
 
class A
{
public:
    A()
    { 
        buf[0] = '\0';
    }    
    A(const char * p)
    {
        strcpy(buf, p);
    }
    
    char buf[80];
};
 
class B : public A
{
public:
    B(const char * str)
    {
        if(strlen(str) < 80)
            A(str);
        else
            ; //......
    }
};
 
int main()
{
    B bb("hello world");
    
    std::cout << '[' << bb.buf << ']';
}
Добавлено через 3 минуты
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
В данном случае на картинке оригинала учебника я вижу лишь возвращение к предыдущей форме.
Чтобы вернуться к предыдущей форме (хотя на самом деле это не формы, а совершенно семантически разные операции - присваивание и иницаилизация) нужно было написать так:
C++
1
*this = String(s);
1
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 15:17  [ТС]
Если бы не было этого else/if, то все выглядело бы вот так:

C++
1
2
3
//----------------
Pstring::Pstring( char s[] ): String(s)
{ }
Вы согласны, что это правильно?
Вернее, если бы мы не делали проверку на размер строки.

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

Добавлено через 14 минут
Я запустил вот такой код:

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
#include <iostream>
#include <string.h> // for "str*" functions
using namespace std;
////////////////////
class String
{
    protected:
        enum { SZ = 80 };
        char str[SZ];
    public:
        String()
        { str[0] = '\0'; }
        String( char s[] )
        { strcpy( str, s ); }
        void display() const
        { cout << str; }
        operator char* ()
        { return str; }
};
//////////////////////////////////
class Pstring : public String
{
    public: 
        Pstring( char s[] );
};
//------------------
Pstring::Pstring( char s[] )
{
    if(strlen(s) > SZ - 1)
    {
        int j = 0;
        for(j; j < SZ - 1; j++)
        {
            str[j] = s[j];
        }
        str[j] = '\0';
    }
    else
        String( s );
}
//------------
int main()
{
    Pstring obj1("some string here...");
    obj1.display();
 
    return 0;
}
При компиляции выбивает только предупреждение:
Bash
1
2
3
4
5
$ g++ test.cpp -o test -g
test.cpp: In function ‘int main()’:
test.cpp:44:36: warning: ISO C++ forbids converting a string constant to ‘char*[-Wwrite-strings]
  Pstring obj1("some string here...");
                                    ^
Все запустилось, но никакого текста нет. Пока не понял, что не так.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
01.08.2019, 15:28
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Все запустилось, но никакого текста нет. Пока не понял, что не так.
А зачем ты делаешь проверку if(strlen(s) > SZ - 1) в классе PString? Она должны быть в конструкторе класса String. Причём не в таком виде
C++
1
2
3
4
5
6
7
String(char s[])
{
    char *p = str;
    for (size_t i = 1; i < SZ && *s; ++i)
        *(p++) = *(s++);
    *p = 0;
}
Добавлено через 1 минуту
А текст не выводится вот из-за этого. Здесь ты не вызываешь конструктор String(), а создаёшь объект String, который сразу удаляется
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
else
* * * * String( s );
0
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 15:38  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
А зачем ты делаешь проверку if(strlen(s) > SZ - 1) в классе PString?
С предыдущих заданий мне достался класс String, который не делает проверки; в новых классах я совершенствую функционал базового класса.

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Здесь ты не вызываешь конструктор String(), а создаёшь объект String, который сразу удаляется
Теперь понял.
Вы случайно не знакомы с gdb? Я бы хотел посмотреть как удаляется этот объект.

Добавлено через 3 минуты
Bash
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
(gdb) b main
Breakpoint 1 at 0x121c: file test.cpp, line 44.
(gdb) run
Starting program: /home/user/work/test 
 
Breakpoint 1, main () at test.cpp:44
warning: Source file is more recent than executable.
44  {
(gdb) s
45      Pstring obj1("some string here...");
(gdb) s
Pstring::Pstring (this=0x7fffffffdef0, s=...) at test.cpp:27
27  Pstring::Pstring( char s[] )
(gdb) 
String::String (this=0x7fffffffdef0) at test.cpp:12
12          { str[0] = '\0'; }
(gdb) 
Pstring::Pstring (this=0x7fffffffdef0, s=...) at test.cpp:29
29      if(SZ - 1 > strlen(s) )
(gdb) 
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:55
55  ../sysdeps/x86_64/multiarch/strlen-avx2.S: No such file or directory.
(gdb) 
56  in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
57  in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
60  in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
61  in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
62  in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
65  in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
66  in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
67  in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
75  in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
335 in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
336 in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
337 in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
341 in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:342
342 in ../sysdeps/x86_64/multiarch/strlen-avx2.S
(gdb) 
Pstring::Pstring (this=0x7fffffffdef0, s=...) at test.cpp:29
29      if(SZ - 1 > strlen(s) )
(gdb) 
31          String::String( s );
(gdb) 
String::String (this=0x7fffffffde80) at test.cpp:12
12          { str[0] = '\0'; }
(gdb) 
Pstring::Pstring (this=0x7fffffffdef0, s=...) at test.cpp:41
41  }
(gdb) 
main () at test.cpp:46
46      obj1.display();
(gdb) 
String::display (this=0x7fffffffdef0) at test.cpp:16
16          { cout << str; }
(gdb) 
main () at test.cpp:48
48  
(gdb) 
49      return 0;
(gdb) k
Kill the program being debugged? (y or n) y
[Inferior 1 (process 1854) killed]
(gdb) q
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
01.08.2019, 15:38
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Вы случайно не знакомы с gdb? Я бы хотел посмотреть как удаляется этот объект.
В смысле - когда удаляется тот String(s);? Он удаляется там, где точка с запятой.
0
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 15:44  [ТС]
И все-таки. Означает ли все выше сказанное, что задание в том виде, в котором
оно задано (и временный объект, и передача по ссылке) без использования
указателя this (который будет в последующих главах) невозможно?

Добавлено через 48 секунд
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
В смысле - когда
Не когда, а как.

Добавлено через 2 минуты
Допустим, я видел удаление объекта в отладчике Visual Studio. Там потом видны нули... Хотелось бы то же самое в gdb. Но это, наверное, не по теме.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
01.08.2019, 15:49
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Не когда, а как.
У тебя там нет деструкторов и объект на стеке, поэтому там вообще ничего не делается.

Добавлено через 3 минуты
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
И все-таки. Означает ли все выше сказанное, что задание в том виде, в котором
оно задано (и временный объект, и передача по ссылке) без использования
указателя this (который будет в последующих главах) невозможно?
Что значит без использования this? Там вроде ясно сказано, что надо Pstring &left(......) {.....; return *this;}
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Для получения лучшего результата используйте
в этих функциях возврат по ссылке, чтобы они могли быть использованы с левой стороны знака "равно" для
изменения существующей строки.
0
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 45
01.08.2019, 16:00  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Что значит без использования this?
Нигде до этого задания в книге автор не объясняет указатели *this -> мы такое не изучали... Поэтому вопрос
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
без использования
указателя this (который будет в последующих главах) невозможно?
актуален.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.08.2019, 16:00
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru