63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116

Перегрузка оператора +

02.08.2014, 17:56. Показов 7991. Ответов 83
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
не получается в своем классе перегрузить оператор + пишет "error C2804: бинарный "operator +" имеет слишком много параметров", действительно задал 2 параметра, но как еще то? ведь + и подразумевает собой сложение 2х значений...
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.08.2014, 17:56
Ответы с готовыми решениями:

Перегрузка оператора ^
Здравствуйте! Необходимо перегрузить бинарный оператор ^ для транспонирования матрицы. Есть класс матрицы: template <class T> ...

Перегрузка оператора +
Написал для перегрузки оператора + class BoolMatrix { private: int feet; public: BoolMatrix(int f): feet(f) {} ...

перегрузка оператора!
Помогите сложить диагонали , при помоши перегрузки оператора+, чтобы можно было написать в maine: c1+c2+c3.заранее спасибо! ...

83
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
02.08.2014, 22:14
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от GetHelp Посмотреть сообщение
-=ЮрА=-, так уже интересно, кое что полезное взял, но не могу протестить, вы забыли дописать перегрузку оператора присваивания на ней у меня как раз сейчас все стопорится... а она точно нужна...
http://codepad.org/Vz17krvX
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
String operator = (const char * str){
        if( text )
            delete text;
        if( str )
        {
            size = strlen(str);
            text = new char[1 + size];
            size = sprintf(text, "%s", str);
            text[size] = 0;
        }
        else
        {
            text = 0;
            size = 0;
        }
        return *this;
    }
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
02.08.2014, 22:15
Цитата Сообщение от GetHelp Посмотреть сообщение
хз я где то читал вроде что delete вызывает free сама...
это разные сущности, хотя и может delete вызывать free, а может не вызывать зависит от компилятора
Цитата Сообщение от GetHelp Посмотреть сообщение
я же показал... так и стоит и никуда не двигается
знаешь мне трудно как то по скриншотам сориентироваться
могу предложить другой путь
"отладочная печать"
после каждого выделения памяти печатаешь на экран значение указателя
например
C++
1
2
ptr = (char*)calloc(size + 1, sizeof(char))
 printf ("Copy constructor ptr=%x",ptr);
да и calloc это не new в случае неудачи исключение не бросит
так что нужно проверять
C++
1
2
3
ptr = (char*)calloc(size + 1, sizeof(char))
   if(ptr==NULL) printf("Error");
 printf ("Copy constructor ptr=%x",ptr);
0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
02.08.2014, 22:19  [ТС]
Цитата Сообщение от Tulosba Посмотреть сообщение
А вот это уже похоже на правду В плюсах постарайтесь забыть про malloc/free.
не могу забыть я лучше забуду в этом классе об new/delete просто очень уж удобная штука realloc, потому что она меняет размер, да еще и копирует элементы при этом
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
02.08.2014, 22:21
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
C++
1
2
if( text )
* * * * * * delete text;
Говорили же уже, что не надо такую проверку делать перед delete. Лучше бы после new проверку добавил, было бы полезнее.
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
C++
1
size = sprintf(text, "%s", str);
strcpy() уже запретили? А учитывая наличие определенной ранее длины можно и вовсе memcpy обойтись.
Копировать одну строку в другую через sprintf - достойно говнокода.
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
C++
1
String operator = (const char * str){
Ссылку надо возвращать, а не копию.
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
02.08.2014, 22:21
Цитата Сообщение от GetHelp Посмотреть сообщение
просто очень уж удобная штука realloc, потому что она меняет размер, да еще и копирует элементы при этом
- нельзя её в плюсах юзать, риаллок из С-ей где совсем другой механизм обработки ошибок, тут вынужден признать, вам "слеует послушать человека который не знает что такое препроцессор" выше
0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
02.08.2014, 22:22  [ТС]
так... сейчас у меня код такой выходит
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
#include <string>
 
class String
{
private:
    char* ptr;
    size_t size;
public:
    String() 
    {
        size = 0;
    }
    String(const char* str)
    {
        size = strlen(str);
        ptr = (char*)calloc(size + 1, sizeof(char));
        strcpy(ptr, str);
    }
    String(const String& str)
    {
        size = str.size;
        ptr = (char*)calloc(size + 1, sizeof(char));
        strcpy(ptr, str.ptr);
    }
    ~String()
    {
        if (size) free(ptr);
    }
    size_t length() const
    {
        return size;
    }
    bool SetLength(size_t NewLength)
    {
        if (!size)
        {
            size = NewLength;
            ptr = (char*)calloc(size, sizeof(char));
        }
        else
        {
            size = NewLength;
            ptr = (char*)realloc(ptr, size * sizeof(char));
        }
        return true;
    }
    const char operator[] (size_t index)
    {
        return ptr[index];
    }
    const char* operator= (const char* str)
    {
        if (size) free(ptr);
        size = strlen(str);
        ptr = (char*)calloc(size + 1, sizeof(char));
        strcpy(ptr, str);
        return str;
    }
    const String operator= (const String& str)
    {
        return operator+ (str.ptr);
    }
    const String operator+ (const char* str)
    {
        size = size + strlen(str) + 1;
        char* tmp = ptr;
        ptr = (char*)calloc(size, sizeof(char));
        strcpy(ptr, tmp);
        free(tmp);
        strcat(ptr, str);
        return *this;
    }
};
кстати ошибки пропали... но теперь не корректно просто сложение работает... например вызываю так
C++
1
2
String str("hello");
str = str + "world";
он мне в str записывает аж 20 символов, там все время повторяется helloworldhelloworld... что бы это значило?
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
02.08.2014, 22:24
GetHelp, убери realloc это действительно важно, хоть и удобно. Его нельзя даже если очень хочется
Цитата Сообщение от GetHelp Посмотреть сообщение
const String operator= (const String& str)
* * {
* * * * return operator+ (str.ptr);
* * }
- убери, юзай КК!
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
02.08.2014, 22:26
Цитата Сообщение от GetHelp Посмотреть сообщение
он мне в str записывает аж 20 символов, там все время повторяется helloworldhelloworld... что бы это значило?
рекурсия однако
сам посмотри что будет, по шагам пройди
нужно предусматривать вариант, когда один аргумент является одновременно и приемником результат
0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
02.08.2014, 22:26  [ТС]
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
убери realloc это действительно важно, хоть и удобно. Его нельзя даже если очень хочется
ладно я попробую что нибудь с этим сделать...
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- убери, юзай КК!
что юзать?
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
02.08.2014, 22:27
Цитата Сообщение от GetHelp Посмотреть сообщение
что юзать?
- конструктор копирования, который был изначально
0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
02.08.2014, 22:39  [ТС]
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
- конструктор копирования, который был изначально
C++
1
2
3
4
5
6
String(const String& str)
    {
        size = str.size;
        ptr = (char*)calloc(size + 1, sizeof(char));
        strcpy(ptr, str.ptr);
    }
этот? как и где его юзать? вы вообще о чем?

вообще я кажется понял что мне нужно, но не знаю как реализовать... мне надо все также перегрузить оператор сложения, НО не менять при этом this и при этом ухитриться вернуть из функции экземпляр String (это самое сложное, поскольку он по прежнему не валиден ) таким образом будет именно сложение, как я понял именно поэтому у меня не хочет нормально складывать...
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
02.08.2014, 22:40
Цитата Сообщение от GetHelp Посмотреть сообщение
этот? как и где его юзать? вы вообще о чем?
Речь об идиоме copy-and-swap (гуглится и, опять же, в книгах описана).
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
02.08.2014, 22:41
GetHelp, миллион советов уже тебе дали по конкретике, не буду повторяться.
Скажу одно, основная и главная проблема твоя в подходе к написанию кода. То, что ошибки ты сейчас самостоятельно или с помощью форумчан, исправишь - это понятно и хорошо. Но вот самый главный шаг нужно с делать в сторону того, чтобы ошибок было изначально меньше.
Начни с разделения ответственности. У тебя есть задача, задача делится на составные части. Каждую составную часть нужно описать отдельно и отдельно оттестировать, а потом собирать все воедино как конструктор. Т.е., вот скажем функция выделения памяти, она у тебя, что называется, прошита во все методы, где используется. каждый раз нужно высчитывать размер умножая на sizeof(char), каждый раз заботиться о проверке, каждый раз смотреть, чтобы указатель не попортился и т.д. Где-то можно что-то и забыть или не так посчитать. В нормальных контейнерах функцию выделения памяти обычно абстрагируют во внутреннюю функцию allocate, а освобождение, соответственно, в deallocate. Инициализация - это тоже отдельная операция. Копирование - тоже. И т.д. Принцип divide et impera очень древний и очень действенный. Не стоит пренебрегать им.
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
02.08.2014, 22:45
Цитата Сообщение от GetHelp Посмотреть сообщение
этот? как и где его юзать? вы вообще о чем?
когда запишешь
String str = String("text") + "data";
Вызовется - КП (коснтруктор преобразования) String("text")
Сработает перегруженный оператор + Strig + char
Сработает КК для str
Если бы стоял оператор присваивания String operator = String мы бы дёрнули делитом битый поинтер text
Касательно кажущегося ликиджа
str = str + "text" его не будет т.к отработает дефолтный String operator = String который по сути присвоит классу самого себя
0
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
02.08.2014, 22:53  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
GetHelp, миллион советов уже тебе дали по конкретике, не буду повторяться.
Скажу одно, основная и главная проблема твоя в подходе к написанию кода. То, что ошибки ты сейчас самостоятельно или с помощью форумчан, исправишь - это понятно и хорошо. Но вот самый главный шаг нужно с делать в сторону того, чтобы ошибок было изначально меньше.
Начни с разделения ответственности. У тебя есть задача, задача делится на составные части. Каждую составную часть нужно описать отдельно и отдельно оттестировать, а потом собирать все воедино как конструктор. Т.е., вот скажем функция выделения памяти, она у тебя, что называется, прошита во все методы, где используется. каждый раз нужно высчитывать размер умножая на sizeof(char), каждый раз заботиться о проверке, каждый раз смотреть, чтобы указатель не попортился и т.д. Где-то можно что-то и забыть или не так посчитать. В нормальных контейнерах функцию выделения памяти обычно абстрагируют во внутреннюю функцию allocate, а освобождение, соответственно, в deallocate. Инициализация - это тоже отдельная операция. Копирование - тоже. И т.д. Принцип divide et impera очень древний и очень действенный. Не стоит пренебрегать им.
не понимаю что конкретно вы имеете ввиду под функциями выделения и освобождения памяти... что толку если я напишу скажем
C++
1
2
3
4
char* allocate(size_t size)
{
return (char*) calloc(size, sizeof(char));
}
что толку? чуть меньше писать при вызове? про остальное тоже самое...

Добавлено через 2 минуты
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
когда запишешь
String str = String("text") + "data";
Вызовется - КП (коснтруктор преобразования) String("text")
Сработает перегруженный оператор + Strig + char
Сработает КК для str
Если бы стоял оператор присваивания String operator = String мы бы дёрнули делитом битый поинтер text
Касательно кажущегося ликиджа
str = str + "text" его не будет т.к отработает дефолтный String operator = String который по сути присвоит классу самого себя
не понимаю о чем вы вы понимаете что КП не возвращает значения? конструкторы вообще не могут возвращать значение ! что именно вы пытаетесь складывать? в конечно счете вы просто присваиваете str = "data"

Добавлено через 3 минуты
т.е. КП вызванный из неоткуда ничего и не дает, вы же не вызываете его от переменной...
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
02.08.2014, 23:00
GetHelp, да ну ё моё, я же всё разложил по полкам
String str = String("text") + data
String("text") - {new String}
{new String} + data = char *operator + (char *)
String str = String(const String new Object)
что тут не ясного?
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
02.08.2014, 23:07
Цитата Сообщение от GetHelp Посмотреть сообщение
что толку? чуть меньше писать при вызове? про остальное тоже самое...
Толк в локализации функциональности в одном месте. Вот приведу пример из самописного класса вектор для POD.
Функция выделения памяти вынесена в отдельный внутренний метод:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    void do_realloc(size_t new_size)
    {
        if(new_size > max)
        {
            throw std::length_error("pod_vector::reserve");
        }
        T* t = (T*)::realloc(m.p, sizeof(T) * new_size);
        if(!t)
        {
            throw std::bad_alloc();
        }
        m.p = t;
        m.a = new_size;
    }
Вот методы, которые ее используют:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    void resize(size_t new_size)
    {
        if(new_size > m.a)
        {
            do_realloc(new_size);
        }
        m.n = new_size;
    }
    void reserve(size_t new_size)
    {
        if(new_size > m.a)
        {
            do_realloc(new_size);
        }
    }
А функции resize и reserve основа для всей остальной функциональности вставки и удаленния. Вот примеры:
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
    template<class Iter>
    void append(Iter f, Iter l)
    {
        size_t n = std::distance(f, l);
        resize(m.n + n);
        std::uninitialized_copy(f, l, m.p + m.n - n);
    }
    template<class Iter>
    void insert(iterator pos, Iter f, Iter l)
    {
        size_t i = pos - m.p;
        size_t n = std::distance(f, l);
        resize(m.n + n);
        pos = m.p + i;
        std::copy_backward(pos, m.p + m.n - n, m.p + m.n);
        std::uninitialized_copy(f, l, pos);
    }
    void push_back(T const & t)
    {
        if(m.a == m.n)
            reserve(m.n ? 2 * m.n : 2);
        m.p[m.n] = t;
        ++m.n;
    }
И теперь представь, если бы мы не выносили это в отдельные методы, а сразу писали все в реализации push_back, append и insert. Они получились бы большие и таким кодом сложно было бы управлять и отлаживать. В противоположность этому, если мы имеем набор отлаженных (пусть и самописных) компонентов, мы сможем жонглировать ими как угодно, и если вдруг какие-либо действия привели к ошибке, у нас всегда будет базовый уровень функциональности, в котором мы уверены. Это сузит круг поиска ошибки и позволит быстрее локализовать проблему. Это и есть принцип "разделяй и властвуй", который я уже упоминал.
1
63 / 64 / 11
Регистрация: 27.02.2013
Сообщений: 1,116
02.08.2014, 23:27  [ТС]
-=ЮрА=-, хз наверное я лучше завтра еще раз свежим взглядом на это посмотрю, но щас хоть убей не понимаю...

DrOffset, я лучше напишу общие аллокаторы...

C стиль
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template <typename T>
T* allocate(T* ptr, size_t size)
{
    T* retval;
    (ptr) ?
        retval = (T*)realloc(ptr, size * sizeof(T)) :
        retval = (T*)calloc(size, sizeof(T));
    return retval;
}
 
template <typename T>
bool deallocate(T* ptr)
{
    bool retval = false;
    if (ptr)
    {
        free(ptr);
        retval = true;
    }
    return retval;
}
C++ стиль
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <typename T>
T* allocate(T* ptr, size_t size)
{
    T* retval = new T[size];
    if (ptr)
    {
        memcpy(retval, ptr, size);
        delete[] ptr;
    }
    return retval;
}
 
template <typename T>
bool deallocate(T* ptr)
{
    bool retval = false;
    if (ptr)
    {
        delete[] ptr;
        retval = true;
    }
    return retval;
}
Добавлено через 4 минуты
з.ы. сразу о возражениях касательно С стиля, да шаблоны это из плюсов, но мой компилятор это глотает... в конце концов важно лишь то в каком стиле происходит аллокация, а не то во что это обернуто...
0
 Аватар для porshe
57 / 51 / 42
Регистрация: 18.07.2014
Сообщений: 194
02.08.2014, 23:29
Цитата Сообщение от 0x10 Посмотреть сообщение
std::string operator"" _s(const char* str, unsigned size) { return std::string(str, size); }
а что это за стандарт? C++11?
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
02.08.2014, 23:30
Цитата Сообщение от porshe Посмотреть сообщение
а что это за стандарт? C++11?
Угу. http://en.cppreference.com/w/c... er_literal
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.08.2014, 23:30

Перегрузка оператора +
Добрый день)Почему то не работает перегрузка оператора сложения) #include &lt;iostream&gt; #include &lt;string&gt; #include...

Перегрузка оператора
#include &lt;cstring&gt; #include &lt;iostream&gt; #include &lt;ctime&gt; #include &lt;cstdlib&gt; using namespace std; class station { public: ...

Перегрузка оператора new[]
Привет всем, программирую давольно давно, на с++ второй год. Столкнулся с задачей, в которой нужно создать свой класс и корректно в нем...

Перегрузка оператора >
Добрый день! #include &lt;stdio.h&gt; #include &lt;tchar.h&gt; #include &lt;iostream&gt; template &lt;typename T1, typename T2&gt; bool ...

Перегрузка оператора
Имеется код: #include &lt;iostream&gt; class X { public: int a; int b; int operator+(int a) {


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Опции темы

Новые блоги и статьи
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru