Подтвердить что ты не робот

Преимущества пустого класса в С++

Какими могут быть возможные преимущества/использование наличия пустого класса?

P.S: Этот вопрос может показаться тривиальным для некоторых из вас, но он предназначен только для обучения и не имеет практического значения. FYI googling не помог.

4b9b3361

Ответ 1

Одно использование будет в шаблоне (мета): например, теги итератора реализованы как пустые классы. Единственная цель здесь - передать информацию во время компиляции, чтобы вы могли проверить, прошел ли итератор, например. функция шаблона удовлетворяет определенным требованиям.

Пример:

Это действительно упрощено, просто для идеи. Здесь цель класса тега - решить, какую реализацию использовать алгоритм:

class forward_iterator_tag {};
class random_access_iterator_tag {};

class MySimpleForwardIterator {
public:
  typedef typename forward_iterator_tag tag;
  // ...
};

class MySimpleRandomIterator {
public:
  typedef typename random_access_iterator_tag tag;
  // ...
};

template<class iterator, class tag>
void myfunc_int(iterator it, tag t) {
  // general implementation of myfunc
}

template<class iterator>
void myfunc_int<iterator, forward_iterator_tag>(iterator it) {
  // Implementation for forward iterators
}

template<class iterator>
void myfunc_int<iterator, random_access_iterator_tag>(iterator it) {
  // Implementation for random access iterators
}

template<class iterator>
void myfunc(iterator it) {
  myfunc_int<iterator, typename iterator::tag>(it);
}

(Надеюсь, у меня все получилось, прошло некоторое время, так как я использовал это...)

С помощью этого кода вы можете вызывать myfunc на произвольном итераторе, и пусть компилятор выбирает правильную реализацию в зависимости от типа итератора (т.е. тега).

Ответ 2

Можно использовать boost::variant, который может содержать значение NULL (SQL), например.

class Null { };

typedef boost::variant<Null, std::string, int> Value;

Чтобы сделать его более полезным, такие вещи, как operator== и operator<<, удобны. Например:

std::ostream& operator<<(std::ostream &lhs, const Null &rhs)
{
     lhs << "*NULL*";
     return lhs;
}

int main()
{
    Variant v("hello");
    std::cout << v << std::endl;
    v = Null();
    std::cout << v << std::endl;
    ...
}

Дает:

hello
*NULL*

Ответ 3

В STL, стандартной библиотеке шаблонов на С++, например, у вас есть

template<class _Arg,
 class _Result>
struct unary_function
    { // base class for unary functions
 typedef _Arg argument_type;
 typedef _Result result_type;
    };

При определении функтора вы можете наследовать unary_function, а затем вы автоматически определяете typedef в своем распоряжении.

Ответ 4

Пустой класс может использоваться как "токен", определяющий нечто уникальное; в определенных шаблонах вам требуется представление-агностическое представление уникального экземпляра, который не имеет значения для разработчика, кроме его уникальности. Одним из примеров является Единица работы; вы можете не беспокоиться о том, что происходит внутри вашего исполнителя, но вы хотите сказать, что исполнитель, что задачи, которые вы им говорите, являются частью атомарного набора. Пустой класс, представляющий Группу работы во внешнем мире, может быть идеальным в этом случае; почти что-либо, что может хранить или выполнять объект Unit of Work (инкапсулирование транзакции БД, выставляя поведение Commit/Rollback), начнет связывать вас с конкретной реализацией, но ссылка на объект полезна для обеспечения уникальной, но с возможностью копирования и пассивной ссылки на атомную набор задач.

Ответ 5

Вы можете использовать его как заполнитель для проверки цели или как средство защиты для специальных функций. Например, в Java существует "пустой" интерфейс Serializable, используемый для указания, является ли класс сериализуемым.

Ответ 6

"пустые" классы означают классы, не имеющие элементов данных? Обычно они объявляют typedefs или функции-члены, и вы можете расширять их своими собственными классами.

Ответ 7

Здесь - интересная ссылка с ответами на вопрос, почему ее разрешено. Возможно, вам будет полезно найти ситуации, когда это может быть полезно.

Ответ 8

Как говорили другие, часто пустой класс (или структура) используется заполнитель, дифференциатор, токен и т.д.

Например, многие люди не знают о том, что существуют новые версии оператора "nothrow". Синтаксис для вызова newhrow new:

p = new(std::nothrow) Bar;

и std:: nothrow определяется просто как

struct nothrow_t {}; //defined in namespace std

Ответ 9

Ответ MartinStettner в порядке, но для того, чтобы выделить важный момент здесь: понятие тегов итератора или, что то другое, теги на С++, не строго зависит от пустых классов. Теги С++, если бы stl-разработчики хотели бы, могли бы быть непустыми классами; который должен работать, но тогда он не добавит никакой дополнительной ценности; по крайней мере, для компиляции акробатики, для которой обычно используется.