Подскажите, как исправить:
class A {
public:
virtual void get() = 0;
};
class A_int : public A {
int i;
public:
A_int(int v) : a(v) {}
virtual int get() {return i;} // error C2555
};
class A_str : public A {
string str;
public:
A_str(const string& v) : str(v) {}
virtual str& get() {return str;} // error C2555
};
void main()
{
list<A*> lst;
lst.push_back(new A_int(1));
lst.push_back(new A_str("something"));
int s;
for(list<A*>::iterator it = lst.begin(); it != lst.end(); it++)
{
if(dynamic_cast<A_int*>(*it) != 0)
s += (*it)->get();
}
}
(в общем, нужна подобная конструкция)
Есть такой шаблон проектирования "визитер":
/////////////////////////////////////////////////////
// модель
//
class Integer;
class String;
class Visitor
{
public:
virtual void Process(Integer &) = 0;
virtual void Process(String &) = 0;
}; // class Visitor..
class Base
{
public:
virtual ~Base() {}
virtual void Visit(Visitor &) = 0;
}; // class Base..
class Integer : public Base
{
int value_;
public: // конструкторы
Integer(int value) :
value_(value)
{
}
public: // селекторы
int Get() const
{
return value_;
}
public: // переопределение поведения
virtual void Visit(Visitor &v)
{
v.Process(*this);
}
}; // class Integer : public Base..
class String : public Base
{
std::string value_;
public: // конструкторы
String(const std::string& value) :
value_(value)
{
}
public: // селекторы
cosnt std::string& Get() const
{
return value_;
}
public: // переопределение поведения
virtual void Visit(Visitor &v)
{
v.Process(*this);
}
}; // class String..
/////////////////////////////////////////////////
// приложение
//
class Total : public Visitor
{
int total_;
public: // конструкторы
Total() : total_(0) {}
public: // селекторы
int Get() const {return total_;}
public: // переопределение поведения
void Process(Integer &v)
{
total_ += v.Get();
}
void Process(String &) {}
};
void main()
{
list<Base*> lst;
lst.push_back(new Integer(1));
lst.push_back(new String("something"));
Total total;
for(list<A*>::iterator it = lst.begin(); it != lst.end(); it++)
(*it).Process(total);
std::cout << "Total :" << total.Get();
}
Исправлю опечатки:
АШ>Есть такой шаблон проектирования "визитер":
АШ>...
АШ> for(list<Base*/*A*/*>::iterator it = lst.begin(); it != lst.end(); it++)
АШ> (*it)/*.*/->/*Process*/Visit(total);
АШ> std::cout << "Total :" << total.Get();
АШ>}
АШ>
Здравствуйте, samarityanin, Вы писали:
S>Подскажите, как исправить:
S>S>class A {
S>public:
S> virtual void get() = 0;
S>};
S>class A_int : public A {
S> int i;
S>public:
S> A_int(int v) : a <- наверно всё же i (v) {}
S> virtual int get() const {return i;} // error C2555
S>};
S>class A_str : public A {
S> string str;
S>public:
S> A_str(const string& v) : str(v) {}
S> virtual str& <- наверно всё же string get() const {return str;} // error C2555
S>};
S>void main()
S>{
S> list<A*> lst;
S> lst.push_back(new A_int(1));
S> lst.push_back(new A_str("something"));
S> int s;
S> for(list<A*>::iterator it = lst.begin(); it != lst.end(); it++)
S> {
S> if(dynamic_cast<A_int*>(*it) != 0)
S> s += (*it)->get();
S> }
S>}
S>(в общем, нужна подобная конструкция)
S>
1) Список нужно чистить. Чтобы не было сюрпризов, надо объявить виртуальный деструктор в классе A. Его отсутствие в данном случае -- грубая ошибка проектирования.
2) Виртуальность у методов get убираем нафик. Из A этот метод выкидываем совсем.
3) Методам get, наверное, стоит добавить const модификатор.
4) Замечаем, что A_int и A_str -- фактически один и то же класс. Заменяем шаблоном.
5) Учимся правильно писать циклы (не по Мейерсу)
for( list<A*>::iterator it=lst.begin(),end=lst.end() ; it!=end ; ++it )
6) Оператор if переписываем так.
if( A_int *object=dynamic_cast<A_int*>(*it) )
s += object->get();
Очень грязный код.
А теперь после маленьких арабских пошли большие римские.
I) Почему list, а не vector? На самом деле, если не нужны вставки в середину, то вектор предпочтительней.
II) Зачем нужно сначала сваливать в кучу разнородные объекты, а потом их опять сортировать по типам? В чем глубокий сакральный смысл поиска приключений на?
... << RSDN@Home 1.1 beta 2 >>