#include <iostream>
#include <string>
using namespace std;
class Counter
{
protected: //NOTE: not private
unsigned int count; //count
public:
Counter() : count(0) //constructor, no args
{ }
Counter(int c) : count(c) //constructor, one arg
{ }
unsigned int get_count() const //return count
{ return count; }
Counter operator ++ () //incr count (prefix)
{ return Counter(++count); }
};
////////////////////////////////////////////////////////////////
class CountDn : public Counter
{
public:
CountDn() : Counter() //constructor, no args
{ }
CountDn(int c) : Counter(c) //constructor, 1 arg
{ }
Counter::operator ++;
CountDn operator -- () //decr count (prefix)
{ return CountDn(--count); }
};
////////////////////////////////////////////////////////////////
class CountPn : public CountDn
{
public:
CountPn(): CountDn()
{}
CountPn(int c): CountDn(c)
{}
CountDn::operator --;
CountPn operator ++ (int)
{ return CountPn(count++); }
CountPn operator -- (int)
{ return CountPn(count--); }
};
////////////////////////////////////////////////////////////////
int main()
{
CountPn a1;
CountPn a2(50);
cout << "\na1=" << a1.get_count(); //display
cout << "\na2=" << a2.get_count(); //display
a1++; a1++; a1++; //increment a1
cout << "\na1=" << a1.get_count(); //display it
a2--; a2--; //decrement a2
cout << "\na2=" << a2.get_count(); //display it
CountDn a3 = ++a2; //create a3 from a2
cout << "\na3=" << a3.get_count(); //display a3
cout << endl;
return 0;
}
Вызов метода из предка наследуемого класcа
Код:
Если я заменю:
Цитата:
CountDn a3 = --a2;
На:
Цитата:
CountDn a3 = ++a2;
Будет выдана ошибка:
Цитата:
error C2675: unary '++' : 'class CountPn' does not define this operator or a conversion to a type acceptable to the predefined operator
Как получить доступ к:
Цитата:
Counter operator ++ ()
{ return Counter(++count); }
{ return Counter(++count); }
?
Посредством using-объявления.
Особенно порадовал вот этот:
Код:
unsigned int count; //count
2. Префиксные операторы у тебя объявлены неправильно. Префиксный оператор обычно возвращает ссылку на экземпляр родного класса.
3. Чтобы сделать оператор базового класса видимым в дочернем достаточно либо использовать using, либо просто объявить его, как у тебя уже проделано в коде для других операторов (на основании этого делаю вывод, что код бездумно содран откуда-то).
4. Только вот сделав оператор ++ видимым ты ничего не добъешся, т.к. он у тебя возвращает Counter, а не CountDn.
5. Я бы советовал переопределять операторы в дочерних классах.
Код:
type operator++()
{
...code...
}
{
...code...
}
Ссылки в следующей главе :)
Пожалуйста приведи пример правильного объявления.
3. (Пока оставим использование using).
Если я добавлю в этот код(отмечено жирным):
Код:
class CountPn : public CountDn
{
public:
CountPn(): CountDn()
{}
CountPn(int c): CountDn(c)
{}
CountDn::operator --;
Counter::operator ++;
CountPn operator ++ (int)
{ return CountPn(count++); }
CountPn operator -- (int)
{ return CountPn(count--); }
};
{
public:
CountPn(): CountDn()
{}
CountPn(int c): CountDn(c)
{}
CountDn::operator --;
Counter::operator ++;
CountPn operator ++ (int)
{ return CountPn(count++); }
CountPn operator -- (int)
{ return CountPn(count--); }
};
Будет выдана ошибка:
Цитата:
error C2603: illegal access declaration: 'Counter' is not a direct base of 'CountPn'
4. Если ты это имееш ввиду
Цитата:
Код:
Counter::operator ++;
, работает..
5. Как мне показалось идея задачи в демонстрации механизмов наследования, без модификации уже имеющихся классов (возможно библиотека будет закрытой...)
P.S. Если не трудно приведи примеры кода, я начинающий и мне действительно трудно понимать на пальцах..
Цитата: EXAngel
2. Разве не так объявляются префиксные операторы?:
Ссылки в следующей главе :)
Пожалуйста приведи пример правильного объявления.
Код:
type operator++()
{
...code...
}
{
...code...
}
Ссылки в следующей главе :)
Пожалуйста приведи пример правильного объявления.
Приведу пример не только объявления, но и определения:
Код:
type& operator++()
{
.....
return *this;
}
{
.....
return *this;
}
т.к. принято, что этот оператор возвращает ссылку на экземпляр, в контексте которого выполняется.
Цитата: EXAngel
3. (Пока оставим использование using).
Если я добавлю в этот код(отмечено жирным):
Будет выдана ошибка:
Цитата:
error C2603: illegal access declaration: 'Counter' is not a direct base of 'CountPn'
В VC 2008 работает. Какой у тебя компилятор?
Цитата: EXAngel
4. Если ты это имееш ввиду , работает..
Должна быть ошибка в строке
Код:
CountDn a3 = ++a2;
что-то типа "cannot convert from 'Counter' to 'CountDn'"
Цитата: EXAngel
5. Как мне показалось идея задачи в демонстрации механизмов наследования, без модификации уже имеющихся классов (возможно библиотека будет закрытой...)
Ну так переопределение в дочерних классах никак не затрагивает код родительских.
Цитата: EXAngel
P.S. Если не трудно приведи примеры кода, я начинающий и мне действительно трудно понимать на пальцах..
Ну как-то так:
Код:
#include <iostream>
#include <string>
using namespace std;
class Counter
{
protected:
unsigned int count;
public:
Counter() :count(0)
{}
Counter(int c) :count(c)
{}
unsigned int get_count() const
{ return count; }
Counter& operator++() {
++count;
return *this;
}
};
class CountDn : public Counter
{
public:
CountDn() :Counter()
{}
CountDn(int c) :Counter(c)
{}
Counter::operator++;
CountDn& operator--() {
--count;
return *this;
}
};
class CountPn : public CountDn
{
public:
CountPn(): CountDn()
{}
CountPn(int c): CountDn(c)
{}
CountDn::operator--;
CountDn::operator++;
CountPn operator++ (int) {
CountPn tmp = *this;
++count;
return tmp;
}
CountPn operator--(int) {
CountPn tmp = *this;
--count;
return tmp;
}
};
int main()
{
CountPn a1;
CountPn a2(50);
cout << "\na1=" << a1.get_count();
cout << "\na2=" << a2.get_count();
a1++; a1++; a1++;
cout << "\na1=" << a1.get_count();
a2--; a2--;
cout << "\na2=" << a2.get_count();
Counter a3 = ++a2;
cout << "\na3=" << a3.get_count();
cout << endl;
return 0;
}
#include <string>
using namespace std;
class Counter
{
protected:
unsigned int count;
public:
Counter() :count(0)
{}
Counter(int c) :count(c)
{}
unsigned int get_count() const
{ return count; }
Counter& operator++() {
++count;
return *this;
}
};
class CountDn : public Counter
{
public:
CountDn() :Counter()
{}
CountDn(int c) :Counter(c)
{}
Counter::operator++;
CountDn& operator--() {
--count;
return *this;
}
};
class CountPn : public CountDn
{
public:
CountPn(): CountDn()
{}
CountPn(int c): CountDn(c)
{}
CountDn::operator--;
CountDn::operator++;
CountPn operator++ (int) {
CountPn tmp = *this;
++count;
return tmp;
}
CountPn operator--(int) {
CountPn tmp = *this;
--count;
return tmp;
}
};
int main()
{
CountPn a1;
CountPn a2(50);
cout << "\na1=" << a1.get_count();
cout << "\na2=" << a2.get_count();
a1++; a1++; a1++;
cout << "\na1=" << a1.get_count();
a2--; a2--;
cout << "\na2=" << a2.get_count();
Counter a3 = ++a2;
cout << "\na3=" << a3.get_count();
cout << endl;
return 0;
}
А ещё лучше вот так:
Код:
class CountPn : public CountDn
{
public:
CountPn(): CountDn()
{}
CountPn(int c): CountDn(c)
{}
CountPn& operator++() {
CountDn::operator++();
return *this;
}
CountPn& operator--() {
CountDn::operator--();
return *this;
}
CountPn operator++ (int) {
CountPn tmp = *this;
++count;
return tmp;
}
CountPn operator--(int) {
CountPn tmp = *this;
--count;
return tmp;
}
};
{
public:
CountPn(): CountDn()
{}
CountPn(int c): CountDn(c)
{}
CountPn& operator++() {
CountDn::operator++();
return *this;
}
CountPn& operator--() {
CountDn::operator--();
return *this;
}
CountPn operator++ (int) {
CountPn tmp = *this;
++count;
return tmp;
}
CountPn operator--(int) {
CountPn tmp = *this;
--count;
return tmp;
}
};
тогда можно будет делать вот так:
Код:
CountPn a3 = ++a2;
что само по себе логично
Цитата:
т.к. принято, что этот оператор возвращает ссылку на экземпляр, в контексте которого выполняется.
Имеется ввиду экзмпляр класса, т.е. ссылку на объект?
А если мне нужно вернуть ссылку только на unsigned int count?
Цитата:
В VC 2008 работает. Какой у тебя компилятор?
У меня VC6 :)
Над остальным ушел думать :D