четверг, 13 мая 2010 г.

explicit template specialization

При написании шаблонного класса бывает необходимо, чтобы разные специализации класса имели разную реализацию какой-то только одной фукнции. Для этого нет необходимости писать вручную специализацию всего класса, достаточно написать специализацию только одной функции. Например:
template<typename T>
class VeryBigClass {
public:
// предполагается, что здесть ещё куча фукнций
double one( int ) {};
// ...


// и ещё одна нешаблонная функция, которую будем определять
void f();
};

// реализация для общего случая
template<typename T> void VeryBigClass<T>::f() { std::cout << "generic" << std::endl; }
// реализация для типа long
template<> void VeryBigClass<long>::f() { std::cout << "long" << std::endl; }

Стандарт разрешает это несмотря на то, что фукнция f() сама по себе не шаблонная. Это разрешается пунктом стандарта C++'03 14.7/3 и ещё есть хороший пример в 14.5.2/2.

Разработчики бывает думают, что код выше невозможен, вероятно, из-за того, что таким способом невозможно написать частичную специализацию класса. Т.е. мы не можем написать функуцию VeryBigClass<T>::f() и ещё одну VeryBigClass<T*>::f() не продублировав определение весего класса ещё раз (либо разбив его на части).

вторник, 11 мая 2010 г.

C++ inheritance

Небольшой пример для объяснения разницы между public, private и protected наследованием:
class A 
{
public:
  int x;
protected:
  int y;
private:
  int z;
};

class B : public A
{
// x is public
// y is protected
// z is not accessible from B
};

class C : protected A
{
// x is protected
// y is protected
// z is not accessible from C
};

class D : private A
{
// x is private
// y is private
// z is not accessible from D
};

Код с ответами, но если убрать комментарии, то можно спрашивать на собеседовании. Ещё интересные моменты: размер класса D такой же как у A, порядок элементов x, y и z не гарантируется (т.е. не факт что &x < &y < &z).