Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Operator overloading + inheritance / 8 сообщений из 8, страница 1 из 1
20.04.2006, 22:30
    #33680799
Landanan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Operator overloading + inheritance
Допустим, есть один класс:

Код: plaintext
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.
//First.h

class first
{
protected:
   int x;
   int y; 
   public:
   first();
   first(int,int);
   first(first&);

friend ostream& operator << (ostream& out, first& obj);


//First.cpp

#include "First.h"

first::first()
{
   x= 0 ;
   y= 0 ;
}

first::first(int _x, int _y)
{
   x=_x;
   y=_y;
}

first::first(first& obj)
{
   x=obj.x;
   y=obj.y
}

friend ostream& operator << (ostream& out, first& obj)
{
   out << obj.x << " " << obj.y;
   return out;
}

Вот, это первый класс. У него имеется наследственный класс:

Код: plaintext
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.
// Second.h

#include "First.h"

class second : public first
{
protected:
   int z;

public:
   second();
   second(int,int,int);
   second(second& obj);

   friend ostream& operator << (ostream& out, second& obj); 


//Second.cpp

#include "Second.h"

second::second() : first()
{
   z= 0 ;
}

second::second(int _x, int _y, int _z) : first(_x,_y)
{
   z=_z;
}

second::second(second& obj) : first(obj)
{
   z=obj.z;
}

ostream& operator << (ostream& out, second& obj)
{
   out << " " << z;
   return out;
}

Вот вопрос: как во втором классе при "перегрузке" оператора сделать чтобы вначале запускался перегруженный оператор класса first, а уж потом добавлялись новые значения (в данном случае z)? Примерно как в случае с конструкторами (для того их и написал).

Уже часа 3 бьюсь и не могу врубиться :(
...
Рейтинг: 0 / 0
21.04.2006, 00:03
    #33680918
redskin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Operator overloading + inheritance
попробуй так

Код: plaintext
1.
2.
3.
4.
5.
6.
ostream& operator << (ostream& out, second& obj)
{
   operator<<(out, static_cast<first>(obj)); 
   out << " " << z;
   return out;
}
...
Рейтинг: 0 / 0
21.04.2006, 11:53
    #33681917
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Operator overloading + inheritance
Я еще хочу добавить, что у тебя здесь неполиморфный метод
operator << (..., const first& f); (именно так кстати, const first & )

Если у тебя будет ссылка типа const first& , но ссылаться она будет реально на
объект класса second, то все равно вызовется метод для first, а данные second не выведутся ( как результат ).

Это делается так : в классе-предке объявляется virtual member function для вывода данного элемента в поток. В этом же классе (один раз !!) пишется operator << (невиртуальный), который в реализации вызывает этот метод вывода в поток. В наследниках метод вывода в поток реализуется, operator << уже не нужно определять.

Вообще, я давно себе принял (и не только я) за хороший стиль определять все операторы только как синтаксические оболочки над какой-то функциональностью, а сама функциональность должна быть реализована в обычных методах. Это и гибче, и позволяет пользователям, которые не любят переопределенные операторы, их не использовать.
...
Рейтинг: 0 / 0
21.04.2006, 13:23
    #33682399
Landanan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Operator overloading + inheritance
автор еще хочу добавить, что у тебя здесь неполиморфный метод
operator << (..., const first& f); (именно так кстати, const first & )

Насчет const - это само-собой разумеется, просто второпях забыл написать :)

авторЭто делается так : в классе-предке объявляется virtual member function для вывода данного элемента в поток. В этом же классе (один раз !!) пишется operator << (невиртуальный), который в реализации вызывает этот метод вывода в поток. В наследниках метод вывода в поток реализуется, operator << уже не нужно определять.

Вообще, я давно себе принял (и не только я) за хороший стиль определять все операторы только как синтаксические оболочки над какой-то функциональностью, а сама функциональность должна быть реализована в обычных методах. Это и гибче, и позволяет пользователям, которые не любят переопределенные операторы, их не использовать.

Если я правильно понимаю, в классе-предке ты предлагаешь сделать что-то типа этого:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
//first.cpp

int first::getX() const
{
   return x;
}

int first::getY() const
{
   return y;
}

ostream& operator << (ostream& out, const first& obj)
{
   out << obj.getX() << " " << obj.getY();
   return out;
}

Вот тут мне все-таки непонятно как перегрузить оператор во втором классе :(
В смысле, как сделать, чтобы, допустим, при команде в main.cpp

Код: plaintext
1.
2.
3.
//main.cpp

second test;
cout << test;

вначале делалось всё, что делалось в первой перегрузке?

Могу, конечно, накатать что-то в этом роде:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
//second.cpp

ostream& operator << (..., second& obj)
{
   out << obj.getX() << " " << obj.getY() << obj.getZ();
   return out;
}

Но это такой "лобовой" метод, я тут не использую написанный ранее код, потому сама идея наследственности получается как-то не особо нужна :(
...
Рейтинг: 0 / 0
21.04.2006, 14:07
    #33682645
redskin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Operator overloading + inheritance
Landanan
Если я правильно понимаю, в классе-предке ты предлагаешь сделать что-то типа этого:

...



Нет. Смысл в том, чтобы для каждого класса написать виртуальную функцию, которая будет выводить его содержимое в поток. Тогда оператор вывода << можно написать в виде обертки только один раз, сделав его другом самого верхнего класса.

Типа такого:

Код: plaintext
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.
class C1
{
    int x;
protected:
    virtual void Print(ostream&) const;
public:
    void SetData(int _x) {x = _x;}
    friend ostream& operator<< (ostream&, const C1&);
};

void C1::Print(ostream& ost) const
{
    ost << x << endl;
}

ostream& operator<< (ostream& ost, const C1& c1)
{
    c1.Print(ost);
    return ost;
}

class C2 : public C1
{
    int y;
protected:
    virtual void Print(ostream&) const;
public:
    void SetData(int _x, int _y) 
    {
        C1::SetData(_x);
        y = _y;
    }
};

void C2::Print(ostream& ost) const
{
    C1::Print(ost);
    ost << y << endl;
}

int main()
{
    C1 c1;
    c1.SetData( 42 );

    C2 c2;
    c2.SetData( 1 , 2 );

    cout << c1 << c2;
    return  0 ;
}


Вот тут мне все-таки непонятно как перегрузить оператор во втором классе :(

Если ты хочешь писать оператор вывода в поток для каждого класса, то чем не устроил тот вариант, который я предложил?
...
Рейтинг: 0 / 0
21.04.2006, 15:00
    #33682909
Landanan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Operator overloading + inheritance
Если ты хочешь писать оператор вывода в поток для каждого класса, то чем не устроил тот вариант, который я предложил?

Первый вариант работает на ура, спасибо тебе за него огромное!
Но все равно хочется узнать разные методы :)
...
Рейтинг: 0 / 0
21.04.2006, 17:46
    #33683565
Landanan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Operator overloading + inheritance
А можно ли как-то приспособить первый вариант для перегрузки оператора >>?

Мой код выглядит примерно так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
istream& operator >> (istream& in, first& x)
{
   in >> x.x >> x.y;
   return x;
}

istream& operator >> (istream& in, second& x)
{
   operator >> (in, static_cast<first>(x));
   in >> x.z;
   return in;
}

И не работает :(

Значения для x.z вводятся нормально, но при попытке отображения второго класса, значения x.x и x.y выводятся те, которые были установлены в first::first();
...
Рейтинг: 0 / 0
21.04.2006, 17:48
    #33683570
Landanan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Operator overloading + inheritance
В предыдущем опечатка.
Правильно так: return in
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Operator overloading + inheritance / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]