2013-05-27 2 views
5

У меня есть несколько файлов заголовков, каждый из которых должен добавить число в массив для регистрации его функций.C добавить в массив в заголовочном файле

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

int register1() { return 100; }; //in header1.h 
int register2() { return 200; }; //in header2.h 
int register3() { return 300; }; //in header3.h 
int register4() { return 400; }; //in header4.h 
int registered[] = {register1(),register2(),register3(),register4()}; //main.c 

Но это довольно неудобно, потому что мне нужно изменить в двух местах, когда я добавлять или удалять файлы заголовков. Лучше было бы изменить только заголовок. Я думал о том, препроцессор определить, так что в каждом заголовке, я могу просто использовать что-то вроде:

#define Registered Registered,100 // header1.h 
#define Registered Registered,200 // header2.h 
int registered[] = {Registered}; // main.c 

Но это, конечно, не будет компилироваться, поскольку новые определения переопределяет старый. Так есть способ добавить определение? Или другой способ добавить число в массив без изменения двух файлов?

Это C, а не C++, иначе я бы использовал экземпляр класса с конструктором, который просто записывал бы в массив. Somethink так:

struct __header1{ __header1() { 
    global_array[global_array_ptr++] = 100; 
} } __header1_inst; 

, а затем преобразовать его в хороший макрос:

#define register(hdr, func) struct __header##hdr{ __header##hdr() { \ 
     global_array[global_array_ptr++] = func; \ 
    } } __header##hdr##_inst; 

    register(1, 100) // header1.h 
    register(2, 200) // header2.h 
+0

Я не думаю, что это возможно. Если вы открыты для этого, здесь предлагается альтернативный подход: http://stackoverflow.com/a/4152185/182748 – asveikau

+0

Сделайте массив больше, чем вам нужно. –

+1

'У меня есть несколько файлов заголовков, каждый из которых должен добавить число в массив для регистрации его функций.' Здесь проблема, это плохая программа, полная жесткой связи. В объектно-ориентированном дизайне каждый модуль должен быть автономным, с максимально возможным количеством зависимостей. Я не знаю, какими должны быть ваши «регистры», поэтому трудно предложить лучший дизайн программы, но поскольку регистры, очевидно, связаны друг с другом, они должны обрабатываться одним модулем. При необходимости модуль регистрации может быть включен из всех этих заголовков. – Lundin

ответ

1

ИМХО, это хак, и я советовал бы против него. Даже если вы можете сделать это на C, рассмотрите ситуацию, когда один такой заголовочный файл включается несколькими модулями. В каждом массиве будет одинаковая запись в глобальном массиве. Далее, хотя вы можете сделать это на C++, порядок инициализации глобального объекта is undefined там, поэтому инициализация другого глобального объекта, основанного на содержимом глобального массива, будет ненадежной.

Кроме того, это действительно сложный способ сделать простую вещь и значительно затушевывает смысл. Помимо того, что сам код заполнения массива является сложным, отслеживание включает в себя обременительные, когда зависимости выходят за рамки тривиальных. Итак, просто заполните этот глобальный массив в определенном месте явно.

Смежные вопросы