LINUX.ORG.RU

C++ создание операторов


0

0

Написал (отчасти в качестве упражнения) простой класс векторов. Впал в ступор при попытках определить оператор присваивания для одного элемента вектора. Т.е. хочу иметь что-то вроде Typename& operator[]=(int, Typename), чтобы можно было изменять отдельные элементы вектора командой типа vector[2]=3.14; Это возможно?

anonymous

Ответ на: комментарий от irq

Именно на присваивание не нашел примера, но вот для +=

Type &Type::operator+=(const Type &i)
{
// твой код
	return *this;
}

irq
()

Typename& operator[](int index) { return data[index]; } const Typename& operator[](int index) const { return data[index]; }

Legioner ★★★★★
()

operator[] у тебя должен возвращать объект т.н. proxy-класса, который умеет две вещи: преобразовываться к Typename (то есть надо ему определить operator Typename) и быть левым операндом оператора присваивания (то есть надо ему определить «operator =»). Вот такой простой, элегантный, интуитивно понятный способ. :) А вообще почитай что-нибудь по C++, того же Мейерса или как там его...

Teak ★★★★★
()
Ответ на: комментарий от Teak

ЗЫ На C++ не пишу, просто этот способ меня в своё время поразил и врезался в память. :)

Teak ★★★★★
()
Ответ на: комментарий от gaa

Народ, я ступил. Оно оказывается у меня уже было - индексирование я уже сделал, о чём и писал в первом посте. Не знал только, что оно симметрично, т.е. что индексированием можно как считывать значение одного элемента, так и присваивать их. Воистину, утро вечера мудренее.

anonymous
()
Ответ на: комментарий от Teak

> operator[] у тебя должен возвращать объект т.н. proxy-класса...

Это изврат. Вполне достаточно возвращать из operator[] неконстантную ссылку. Это очень такой удобный встроенный тип, который обладает перечисленными тобой свойствами ;-)

#include <iostream>

template<class T> class AlmostAVector {
public:
    AlmostAVector(size_t init_size = 10) {data = new T[init_size];};
    T& operator[](size_t index) {return data[index];};
private:
    T *data;
};

int main() {
    AlmostAVector<int> v;
    v[0] = 12;
    std::cout << v[0] << std::endl;
    v[0] = 15;
    std::cout << v[0] << std::endl;
}

anonymous
()
Ответ на: комментарий от anonymous

> Это очень такой удобный встроенный тип, который обладает перечисленными тобой свойствами ;-)

Это неспортивно^Wnot C++ way. :) Слишком просто, в общем. :)

Teak ★★★★★
()
Ответ на: комментарий от anonymous

>Вполне достаточно возвращать из operator[] неконстантную ссылку. Это очень такой удобный встроенный тип, который обладает перечисленными тобой свойствами T& operator[](size_t index) {return data[index];};

Да-да, именно так я и сделал. ПС последний семиколон - разве не лишний?

anonymous
()
Ответ на: комментарий от Teak

> Это неспортивно^Wnot C++ way. :)

Однако ж так весь STL написан.

> Слишком просто, в общем. :)

Ну, на самом деле C++ - собрание очень простых концепций. Просто их очень много ;-)

P.S.: Да, точки с запятой после определения методов, конечно, лишние.

anonymous
()
Ответ на: комментарий от Teak

> operator[] у тебя должен возвращать объект т.н. proxy-класса, который умеет две вещи: преобразовываться к Typename (то есть надо ему определить operator Typename) и быть левым операндом оператора присваивания (то есть надо ему определить «operator =»). Вот такой простой, элегантный, интуитивно понятный способ. :) А вообще почитай что-нибудь по C++, того же Мейерса или как там его...

Да, кстати - такое тоже может понадобиться, чтобы избежать в своем контейнере классических граблей на тему

if (someset[somekey]) { /* а вот тут мы создали новый объект, хотя, вероятно, не хотели */ do_smth()}

когда надо было вместо этого написать

if (someset.find(somekey) != someset.end()) {}

что, конечно, гораздо корявее.

А с использованием проксей можно было бы, скажем, возвращать объект, который кастится к bool давая false, позволяет записать что-то в контейнер через себя, и кидает исключение при попытке "чтения", т.е. конвертации в data_type - что-то типа перлового undef.

anonymous
()
Ответ на: комментарий от anonymous

> А с использованием проксей можно было бы, скажем, возвращать объект, который кастится к bool давая false, позволяет записать что-то в контейнер через себя, и кидает исключение при попытке "чтения", т.е. конвертации в data_type - что-то типа перлового undef.

угу, а потом ловить грабли из-за непоняток, к какому типу приведётся полученное значение

gaa ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.