Я разрабатываю класс для своего процессора AVR.
Класс будет обрабатывать все операции, связанные с портом, такие как Set, Read и т. Д.; Конструктор выглядит так:
(...)
public:
Port(volatile uint8_t * DDR, volatile uint8_t * PORT);
(...)
И он построен в начале main()
:
int main()
{
Port PortA(&DDRA, &PORTA);
(...)
}
Теперь я хочу убедиться, что нигде в объекте программы с одинаковыми параметрами не будет построено. Уверен, что я не могу создать массив или карту, чтобы узнать это и выбросить исключение. Это должно быть сделано во время компиляции. Поэтому я хочу заставить avr-g++ проверить, существует ли в текущем проекте какой-либо другой порт (тот же самый первый параметр или тот же второй параметр).
Все функции используют указатели/ссылки на объекты Port.
Как насчет следующего?
Адрес указателей должен быть известен во время компиляции.
template<int *p>
class Tester
{
public:
static Tester& GetInstance()
{
static Tester t;
return t;
}
private:
Tester() {}
};
int i;
int main()
{
Tester<&i>& t = Tester<&i>::GetInstance();
}
Если вам нужен только один экземпляр класса, зачем использовать классы? Вся цель занятий состоит в том, что вы можете иметь несколько целей. Просто придерживайтесь глобальных переменных и бесплатных функций.
@Neil Kirk
Если отказ предоставить объявление ctor вообще для единицы компиляции приводит к неопределенному поведению, тогда есть способы решить это.
class t
{
#ifdef ALLOW_CTOR
public:
#else
private:
#endif
t(int i);
public:
~t();
int get();
private:
int m_i;
};
отмечает ctor как общедоступный в одном, но закрытый во всех других единицах компиляции, что приводит к четко определенной ошибке: невозможность доступа к частной функции-члену.
Это некрасиво, но он выполняет свою работу. 10-летний опыт говорит, что встроенная работа имеет тенденцию быть подобной этому временами. :/
Я тестировал это с помощью простого класса под MSVC, вам придется адаптироваться для ваших нужд, но он демонстрирует принцип.
Объявите свой класс следующим образом в заголовке:
class t
{
public:
#ifdef ALLOW_CTOR
t(int i);
~t();
#endif
int get();
private:
int m_i;
};
Затем в ровно один файл добавьте строку:
#define ALLOW_CTOR 1
включить заголовочный файл, объявить экземпляры порта как переменные области файла, а затем реализовать все методы класса вашего класса, ctor, dtor, accessors и т.д.
Если вы не помещаете ALLOW_CTOR
в другие исходные файлы, они все равно могут использовать методы доступа в вашем классе, но они не могут использовать конструктор. В отсутствие правильного конструктора MSVC жалуется, потому что он пытается использовать конструктор копии по умолчанию, но поскольку списки параметров не совпадают, он терпит неудачу. Я подозреваю, что используемый вами компилятор не сработает, я просто не уверен, что произойдет с отказом.