IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Перегрузка операторов
сообщение
Сообщение #1


Ночной волк
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской

Репутация: -  1  +


#include <iostream.h>

class a {
double x;
public:
void operator++(){
this->x = x+9;
return;
};
friend a operator--(a &b){
b.x = b.x-9;
return b;
};
a operator+(a &c){
(this->x)+=(c.x);
return *this;

};
friend a operator-(a &b, a &c){
a temp;
temp.x=(b.x)-(c.x);
return temp;
};

print(){
cout<<x;
cout<<endl;
};

a(){
x=1;
};
};

int main() {
a kot;
kot.print();
++kot;
cout << endl;
kot.print();
--kot;
kot.print();
a rot, mot;
++rot;
mot = kot+rot;
mot.print();


return 1;
}

Просто перегрузка операторов. При этом минусы - друзья, плюсы - функции члены. Я делаю функции встраиваемыми просто для удобства.

В принципе все работает, но функция Принт вызывает warning. Насколько эффективна программа, нет ли каких других неточностей?

Да, вот еще, как реализуется постфиксная запись? Можно ли делать кардинально разные реализации для разных типов вызова операторов?


--------------------
Не думай о белой обезьяне.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Цитата
функция Принт вызывает warning
На более жестком компиляторе это предупреждение тут же становится ошибкой: нельзя описывать функцию без типа возвращаемого значения. Ничего не возвращает - значит void...

Цитата
Да, вот еще, как реализуется постфиксная запись?
Ты имеешь в виду, как реализуется постфиксный инкремент/декремент? Очень просто, в префиксном нет параметров, а в постфиксном в качестве параметра передается int (просто, чтобы отличить одно от другого, так принято делать), то есть, если префиксный был:
void operator++();
// то постфиксный -
void operator ++(int);
// или
friend a operator++(a &b, int);


А вот теперь - касательно ответа на вопрос:
Цитата
Насколько эффективна программа, нет ли каких других неточностей?
А как, прости, ты будешь различать префикс и постфикс, если префиксный вариант ++ у тебя ничего не возвращает? Весь смысл-то и есть в различии, что префикс возвращает измененное значение, а постфикс - НЕизмененное. Сделай вот так, например:
#include <iostream.h>
class a {
friend ostream& operator << (ostream& os, a& obj) {
os << obj.x;
return os;
}

private:
double x;
public:
a& operator++() {
this->x += 9;
return *this;
}
a& operator++(int) {
a& copy = *this;
this->x += 9;
return copy;
}

friend a operator--(a &b) {
b.x = b.x-9;
return b;
}
a operator + (a &c) {
(this->x)+=(c.x);
return *this;
}
friend a operator-(a &b, a &c){
a temp;
temp.x=(b.x)-(c.x);
return temp;
}
void print() {
cout<<x<<endl;
}

a() {
x = 1;
}
};

int main() {
a kot;
// kot.print();
cout << ++kot << endl;
cout << kot << endl;
cout << kot++ << endl;
cout << kot << endl;

// kot.print();
--kot;
kot.print();
a rot, mot;
++rot;
mot = kot+rot;
mot.print();
return 0; // no errors
}
, и поиграйся с этой реализацией, посмотри, на что она способна...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Ночной волк
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской

Репутация: -  1  +


Цитата
нельзя описывать функцию без типа возвращаемого значения.

blink.gif
Вот это я баран... Ошибка из цикла "бабушка и очки"...

Не работает..

a operator++(int) {
a copy = *this;
this->x += 9;
return copy;



По моему, темповская переменная должна быть объектом, а не ссылкой. Но как вернуть ссылку на нее?

a& operator++(int) {
a copy = *this;
this->x += 9;
return & copy; //берем адрес copy


Так че-то не работает.

При возврате функции создается еще одна копия copy, вызывается конструктор и этой копии присваивается значение copy. Я верно мыслю? Так как избежать этого?


--------------------
Не думай о белой обезьяне.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Цитата
Не работает..
А я тебе это и не предлагал... То, что я написал - прекрасно отработало под GCC...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Ночной волк
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской

Репутация: -  1  +


У меня MSV6.
Все ты меня теперь совсем запутал.
a& operator++(int) {//оператор возвращает ссылку на тип а
a& copy = *this; //тут создается ссылочная переменная указывающая на this
this->x += 9; // тут мы меняем this объект
return copy; // тут мы возвращаем ссылку на this


Где ошибка?

MS так все и делает. А что тогда делает ГНУ? Компиляторы разные, но язык один. wacko.gif

a& operator++(int) {//оператор возвращает ссылку на тип а
a copy = *this;
this->x += 9;
return & copy; // берем адрес copy и возвращаем его, поскольку он
// содержит то самое значение которое было ДО


А здесь где ошибка?


--------------------
Не думай о белой обезьяне.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Цитата
А здесь где ошибка?
Ты действительно не видишь разницы между ССЫЛКОЙ и АДРЕСОМ? По какому праву ты хочешь вернуть из метода АДРЕС, когда в заголовке написано, что метод должен возвращать ССЫЛКУ?

Цитата
Где ошибка?
У тебя что, там ошибка? Ни Intel C++, ни GNU, ни Cameau ошибок не видят... По-моему ты сам себя запутал... Если у тебя что-то не компилируется, или не работает - показывай, в какой строке, и что именно происходит... Я компиляторами от MS не пользуюсь, проверить, что там делает MSVC не могу...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Ночной волк
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской

Репутация: -  1  +


Цитата
Ты действительно не видишь разницы между ССЫЛКОЙ и АДРЕСОМ? По какому праву ты хочешь вернуть из метода АДРЕС, когда в заголовке написано, что метод должен возвращать ССЫЛКУ?

Хм...Логично. Честно говоря я постоянно путаю куда поставить амперсанд...
Не суди строго, я учу это вторую неделю. И С я до этого тоже знал в общих чертах(ни черта не знал).

Не ошибка просто участок
cout << ++kot << endl;
cout << kot << endl;
cout << kot++ << endl;
cout << kot << endl;


выводит
10
10
19
19
Хотя должен (я думаю, что должен)
10
10
10
19
Поэтому я начал мудрить. Фраза "Не работает.." не относится к коду под ним, забыл поставить прогал.


Это как раз работает, причем так как я предполагаю, но создает лишнюю копию:
a operator++(int) {
a copy = *this;
this->x += 9;
return copy;



P.S. Извини если туплю.. Это сезонное..


--------------------
Не думай о белой обезьяне.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Хорошо... Что говорит MSVC вот на такой код?
#include <iostream.h>
class a {
friend ostream& operator << (ostream& os, const a& obj) { // Заметь, здесь const !!!
os << obj.x;
return os;
}

private:
double x;
public:
a& operator++() {
this->x += 9;
return *this;
}

a operator++(int) {
a copy(*this);
this->x += 9;
return copy;
}

a() {
x = 1;
}
};
int main() {
a kot;
cout << ++kot << endl;
cout << kot << endl;
cout << kot++ << endl;
cout << kot << endl;

return 0;
}
(это каноническая форма перегрузки пре/пост-фиксного инкремента, взято из книги "C++ Coding Standards" Саттера и Александреску)...

Если при перегрузке операции вывода убрать const, программа тут же перестанет компилироваться... Что теперь выводится?

Кстати, цитата оттуда:
Цитата
In calling code, prefer using the prefix form unless you actually need the original value returned by the postfix version. The prefix form is semantically equivalent, just as much typing, and often slightly more efficient by creating one less object. This is not premature optimization; it is avoiding premature pessimization
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Ночной волк
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской

Репутация: -  1  +


Так работает правильно..
Цитата
Если при перегрузке операции вывода убрать const, программа тут же перестанет компилироваться...

Убрал. Ниче не изменилось, снова работает правильно.


--------------------
Не думай о белой обезьяне.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






Не должно компилироваться... Ну, понятно, Стандарт языка не для MS... Ладно, закончим флейм на этом...

Так что не волнуйся о создании лишнего экземпляра, оно так и должно быть...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Ночной волк
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской

Репутация: -  1  +


Ок, понятно спасибо smile.gif


--------------------
Не думай о белой обезьяне.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.10.2020 12:04
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name