Lect17
.pdf17.Обобщенное программирование.Итераторы.
«Объектно-ориентированное программирование»
доцентПриваловМ.В.
Донецк,ДонНТУ,2011
1
Контрольныевопросы
Какиепараметрышаблонамогутне являтьсятипами?
Чтотакоеспециализацияшаблонаидля чегоонаприменяется?
Какописываетсяшаблонныйметод, принадлежащийклассу?
Каковыограничениянаследования шаблонов?
Длякакихцелейиспользуется наследованиешаблоновотпростых классов?
2
Наследованиепростыхклассов отшаблонов
Примерзадачи– подсчетколичества существующихэкземпляровобъектов некоторыхклассов
Решение:
◦Создатьбазовыйшаблонныйкласс,конструкторы (поумолчаниюикопирования)идеструктор которогоосуществляютинкремент/декремент счетчика
Вкачествепараметрашаблонабудетвыступатькласс,для которогонеобходимовестиподсчетэкземпляров
◦Классы,длякоторыхнеобходимовестиучет количестваэкземпляровпубличнонаследуются откласса-счетчика
3
Наследованиепростыхклассов
отшаблонов.Код.
template <class T> class Countable { public:
static size_t GetInstanceCount() { return m_counter;
}
protected: Countable() {
++m_counter;
}
Countable(Countable const& other){ ++m_counter;
}
~Countable() { --m_counter;
}
private:
static size_t m_counter; };
template<class T> size_t Countable<T>::m_counter = 0;
4
Наследованиепростыхклассов отшаблонов.Код.
// Правда, это здорово?
class SomeClass : public Countable<SomeClass> { public:
};
int main(int argc, char* argv[]) { SomeClass someObject;
std::cout << SomeClass::GetInstanceCount() << "\n";
// Мы ведь уже всё знаем об областях видимости, не так ли? ;)
{ SomeClass someOtherObject;
} std::cout << SomeClass::GetInstanceCount() << "\n"; std::cout << SomeClass::GetInstanceCount() << "\n";
}return 0;
Результаты:
1
2
1
5
Наследованиепростыхклассов отшаблонов
Пример2:иерархиягеометрических
фигур. IShape
IRectangle ICircle
Rectangle |
Circle |
6
Реализациябезшаблонов
class Color {…};
class IShape { public:
virtual Color GetColor()const=0
virtual void SetColor(Color const& c)=0; virtual double GetArea()const=0;
};
class IRectangle : public IShape {
…
};
class ICircle : public IShape {
…
};
7
Реализациябезшаблонов
|
class Circle : public ICircle { |
|
class Rectangle: public IRectangle { |
|
|
|||
|
public: |
|
public: |
|
|
|||
|
… |
|
… |
|
|
|||
|
virtual Color GetColor()const |
|
virtual Color GetColor()const |
|
|
|||
|
{ |
|
|
{ |
|
|
|
|
|
return m_color; |
|
return m_color; |
|
|
|||
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
virtual Color SetColor(Color const& c) |
|
|
|
virtual Color SetColor(Color const& c) |
|
{ |
|
|
|||
|
|
|
|
|||||
|
{ |
|
|
|
|
|
|
|
|
m_color = c; |
|
m_color = c; |
|
|
|||
|
} |
|
|
} |
|
|
|
|
|
virtual GetArea()const |
|
virtual GetArea()const |
|
|
|||
{ |
|
{ |
|
|
|
|
||
|
return PI * m_radius * m_radius; |
|
return m_width * m_height; |
|
|
|||
} |
|
} |
|
|
|
|
||
|
private: |
|
private: |
|
|
|||
|
Color m_color; |
|
|
|
Color m_color; |
|
|
|
|
double m_radius; |
}; |
|
double m_width, m_height; |
|
|
||
}; |
|
|
|
8 |
|
Устраняемдублированиекода
Создадимабстрактныйшаблонныйкласс ShapeImpl, реализующийвиртуальныеметодыдля установкииполученияцвета
◦Вкачествепараметрашаблонабудетвыступатьбазовый класс:
template <class Base>
class ShapeImpl : public Base {…};
◦Классявляетсяабстрактным,т.к.оннереализуетметод вычисленияплощади.
КлассыCircle иRectangle будутнаследоватьсяот
ShapeImpl
◦ВкачествепараметратипавыступаютинтерфейсыIСircle и IRectangle соответственно:
class Circle : public ShapeImpl<ICircle> {…};
9
Исправленнаяиерархия
IShape
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IRectangle |
|
|
|
ICircle |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ShapeImpl<IRectangle> ShapeImpl<ICircle>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rectangle |
|
|
|
Circle |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10