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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.94
GetHelp
-8 / 60 / 6
Регистрация: 27.02.2013
Сообщений: 1,112
02.08.2014, 17:56     Перегрузка оператора + #1
не получается в своем классе перегрузить оператор + пишет "error C2804: бинарный "operator +" имеет слишком много параметров", действительно задал 2 параметра, но как еще то? ведь + и подразумевает собой сложение 2х значений...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.08.2014, 17:56     Перегрузка оператора +
Посмотрите здесь:

Перегрузка оператора C++
C++ Перегрузка оператора +=
Перегрузка оператора = C++
Перегрузка оператора * C++
Перегрузка оператора ~ C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6442 / 3816 / 885
Регистрация: 30.01.2014
Сообщений: 6,610
02.08.2014, 23:39     Перегрузка оператора + #81
Цитата Сообщение от GetHelp Посмотреть сообщение
DrOffset, я лучше напишу общие аллокаторы...
Да без проблем. Именно к этому я тебя и подвожу. Остальные моменты (не обязательно в текущей задаче) точно так же поддаются разбиению на подзадачи. Все, что выше - это была лишь иллюстрация, чтобы ты понял.

Кстати realloc работает как malloc (или calloc) если первым аргументом передан NULL. Так что смысла той проверке в С-варианте нет.

Еще вот добавлю:
Очень многие в ответах на форуме пишут, так сказать, иллюстрационный код, чтобы пояснить идею. Это не значит (и не должно значить), что это законченный и готовый к использованию продукт. Так что копипастить с форума к себе в проект идея потенциально чреватая ошибками. Отсюда вот такие посты:
"форумчанин": сделай то и то.
"ТС": сделал - не помогло.
Как правило "сделал" в этом случае означает копипаст в проект и пробный запуск. А в идеале надо бы разобраться с тем, что же предлагается. Откуда растут ноги и почему. Допустим загуглить или спросить еще раз в уточняющем посте.
Так и в нашем с тобой случае, вот я тебе советую нечто. Привожу конкретный пример с аллокацией (кстати посомори как сделано в std::vector - там все именно так, как я тебе предлагаю), но вот это совсем не значит, что нужно править только аллокацию. Я тебе предлагаю в целом изменить подход. Писать функции так, чтобы они решали одну конкретную задачу, если задача слишком сложна, стоит разбить ее на подзадачи и решить сначала их. Оттестировать, продолжить далее. Твои ошибки типичные, в том числе потому, что в голове почти любого человека не может поместиться слишком много информации одновременно. Когда задача разрастается, становится очень сложно решать вопросы, т.к. за мелочами скрывается суть (поговорка "за деревьями леса не видно"). Один из самых эффективных способов борьбы с такой сложностью - это повышение уровня абстракции (разделяй и властвуй). Есть такое крылатое выражение "Любую проблему можно решить повышением уровня абстракции, кроме проблемы слишком большого числа абстракций", это и указание и предостережение. С одной стороны понятно как решать вопросы, с другой стороны понятно что грозит, если слишком этим увлечься.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
GetHelp
-8 / 60 / 6
Регистрация: 27.02.2013
Сообщений: 1,112
03.08.2014, 00:44  [ТС]     Перегрузка оператора + #82
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void* c_allocate(void* ptr, size_t size)
{
    void* retval;
    (ptr) ?
        retval = realloc(ptr, size * sizeof(ptr)) :
        retval = calloc(size, sizeof(ptr));
    ptr = retval;
    return retval;
}
 
void c_deallocate(void* ptr)
{
    if (ptr) free(ptr);
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <typename T>
T* cpp_allocate(T* ptr, size_t old_size, size_t new_size)
{
    T* retval = new T[new_size];
    if (ptr)
    {
        memcpy(retval, ptr, old_size);
        delete[] ptr;
    }
    ptr = retval;
    return retval;
}
 
template <typename T>
void cpp_deallocate(T* ptr)
{
    if (ptr) delete[] ptr;
}
Добавлено через 44 минуты
DrOffset, я ничего не откуда не копипастил, я вообще не смотрел то что вы там кидали... код полностью мой... но впрочем я ушел от темы, про аллокаторы открыл новую
DrOffset
6442 / 3816 / 885
Регистрация: 30.01.2014
Сообщений: 6,610
03.08.2014, 02:34     Перегрузка оператора + #83
Цитата Сообщение от GetHelp Посмотреть сообщение
я ничего не откуда не копипастил, я вообще не смотрел то что вы там кидали
Это кстати зря, что не смотрел.
Да я и не про себя говорил. И даже не про тебя, т.е. я не имел в виду тебя, когда писал про копипаст. Я вообще говорил о тенденции (это очень часто здесь встречается) и о соблазне брать что дают не особо разбираясь. А потом был переход уже на нашу ситуацию и предостережение не понимать буквально то, о чем я тебе пишу, а постараться вникнуть в то, зачем вообще это нужно. Вот о чем был пост.

Кстати твой класс в первом приближении можно описать всего двумя методами: assign и append.
Примерно так, назовем этот класс DumbString (потому что он простой):
Кликните здесь для просмотра всего текста

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
#include <iostream>
#include <cstring>
#include <cstdlib>
 
class DumbString
{
public:
    typedef char value_type;
 
    DumbString()
        : size_(), data_()
    {}
 
    DumbString(value_type const * str)
        : size_(), data_()
    {
        assign(str, std::strlen(str));
    }
    DumbString(value_type const * str, size_t len)
        : size_(), data_()
    {
        assign(str, len);
    }
    DumbString(DumbString const & other)
        : size_(), data_()
    {
        assign(other.data_, other.size_);
    }
    DumbString & operator=(DumbString const & other)
    {
        if(this != &other)
        {
            assign(other.data_, other.size_);
        }
        return *this;
    }
    DumbString & operator=(value_type const * str)
    {
        assign(str, std::strlen(str));
        return *this;
    }
 
    ~DumbString()
    {
        deallocate(data_);
    }
 
    size_t length() const
    {
        return size_;
    }
    char & operator[](size_t index)
    {
        return data_[index];
    }
    char operator[](size_t index) const
    {
        return data_[index];
    }
 
    DumbString operator+(const char * str)
    {
        DumbString ret(*this);
        ret.append(str, std::strlen(str));
        return ret;
    }
    DumbString operator+(DumbString const & other)
    {
        DumbString ret(*this);
        ret.append(other.data_, other.size_);
        return ret;
    }
 
    value_type const * c_str() const
    {
        return data_ ? data_ : "";
    }
 
    void clear()
    {
        deallocate(data_);
        data_ = 0;
        size_ = 0;
    }
private:
    void assign(value_type const * str, size_t len)
    {
        if(len)
        {
            if(size_ != len)
            {
                data_ = reallocate(data_, len + 1);
                size_ = len;
            }
            std::memcpy(data_, str, len);
            data_[size_] = 0;
        }
        else
        {
            clear();
        }
    }
    void append(value_type const * str, size_t len)
    {
        if(len)
        {
            data_ = reallocate(data_, size_ + len + 1);
            std::memcpy(data_ + size_, str, len);
            size_ = size_ + len;
            data_[size_] = 0;
        }
    }
 
    static value_type * reallocate(value_type * data, size_t n)
    {
        value_type * m = static_cast<value_type*>(std::realloc(data, sizeof(value_type) * n));
        if(!m)
        {
            throw std::bad_alloc();
        }
        return m;
    }
 
    static void deallocate(value_type * data)
    {
        std::free(data);
    }
 
private:
    size_t       size_;
    value_type * data_;
};
 
int main()
{
    DumbString a = "test";
    DumbString b = "string";
    DumbString c = "";
    DumbString d;
 
    DumbString a1 = a + " " + b;
 
    std::cout << a1.c_str() << std::endl;
    a1 = "abc";
    std::cout << a1.c_str() << std::endl;
}

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

Итак, вернемся к сути. Пример выше демонстрирует насколько важно проводить декомпозицию задачи: практически весь функционал класса реализуется всего двумя методами. Мы выделили самые базовые версии этих методов и взяли их за основу в реализации всех остальных.
Надеюсь, теперь я донес мысль.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.08.2014, 10:46     Перегрузка оператора +
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
03.08.2014, 10:46     Перегрузка оператора + #84
правильная по Дзен перегрузка оператор+ - в виде свободной функции
C++
1
2
3
4
5
T operator+(const T& a, const T& b)
{
    T result(a);
    return result += b;
}
Yandex
Объявления
03.08.2014, 10:46     Перегрузка оператора +
Ответ Создать тему
Опции темы

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