Вопрос

У меня есть некоторый код, в котором есть система динамических классов на C ++, в которой есть элемент с именем GetClassName(), довольно безобидное имя, которое можно было бы себе представить.Однако при включении в большой проект с заголовками Windows весь ад вырвался на свободу.Очевидно, Windows использует #define GetClassName (GetClassNameA или GetClassNameW), который все портит, и мое виртуальное дерево вызовов запуталось, из-за чего я потерял день на глупую отладку компилятора в темноте, пытаясь выяснить, что было не так.

Итак, помимо того, что я проклинаю Microsoft за использование такого ужасно легко конфликтующего имени для #define (я имею в виду, что кто-то, честно говоря, должен быть застрелен за это!) Я прошу о 3 целях.

  1. Какое еще подходящее название для GetClassName() ?
  2. Есть в любом случае чтобы исправить это, так что в будущем, прочая разработчики из моей базы кода не ждет подобная судьба
  3. И для потомков, когда кто-то другой столкнется с подобным необъяснимая ошибка
Это было полезно?

Решение

Я бы переименовал этот метод.

Конечно, можно сказать

#include <windows.h>
#undef GetClassName

но это не чисто, пользователи чьего-либо кода должны помнить, что нужно писать ::GetClassNameW при вызове функции win32.

Можно предоставить методы GetClassNameA и GetClassNameW в своем классе, но это просто некрасиво.

Я вижу два подхода :либо удлините, либо сократите название:)

1) добавьте префикс для всех функций в подсистеме, например TI_ (для получения информации о типе):

TI_GetClassName() 
TI_GetBaseClass() 
TI_IsDerivedFromClass()
etc  

2) или поместить их в какой-нибудь интерфейс iCLASS

interface IClass {
GetName();
GetBase(); 
IsDerivedFrom();
etc

и верните этот интерфейс из одного метода,
таким образом, функция GetClassName() становится

GetClass()->GetName()

Другие советы

  1. ClassGetName()
  2. #undef GetClassName
  3. WinAPI - это C-API.Никаких пространств имен.Некоторые другие платформы пытаются смягчить это, добавляя префиксы ко всем названиям символов, но в конечном итоге и это разваливается.Лучший выбор:если вы пишете код, который не зависит от заголовков SDK платформы Windows, тогда не надо #include они.

Возможно, GetWindowClassName?На самом деле GetClassName - неплохое название для этого API, поскольку оно относится к оконным классам.Реальная проблема заключается в том, что это объявление C API, а в объявлениях C нет способа ввести повторно используемое объявление, которое не загрязняет глобальное пространство имен.

Это в гораздо большей степени недостаток языка Си, чем Microsoft.

Windows API битком набит макросами с чистыми именами, которые расширяются до имен функций с суффиксом, указывающим ASCII / UTF-16, в зависимости от параметров сборки.Было бы неплохо, если бы они добавляли ко всему префикс "W32" или аналогичный (а-ля "NS" в OS X), но они решили не делать этого, по-видимому, чтобы сохранить API "чистым".

Поскольку изменить ваш код намного проще, чем их API, вот несколько предложений:

1) Изучите Windows API (на самом деле он не такой уж большой!) или, по крайней мере, ознакомьтесь с MSDN чтобы вы могли искать конфликты имен, когда сталкиваетесь с необъяснимым потоком работы программы.

2) Используйте явное разрешение области видимости в своем коде там, где вы можете (MyClass::GetClassName()).К сожалению, это нарушит отправку виртуальных функций, поэтому будьте осторожны с этим.

3) Используйте другое соглашение об именовании в своем коде.MS всегда использует camelCase, поэтому вы не столкнетесь, если выберете какое-то другое соглашение (get_class_name(), GetClassName() и т.д.).

4) Лично я ненавижу называть свои средства получения и настройки "getX ()" и "SetX()", но предпочитаю полагаться на механизм перегрузки и использовать "xtype X() const" для средств получения и "void X (xtype newval)" для средств установки.Ваш пробег может отличаться, но я нахожу его более чистым, и get / set очевиден из аргументов.Очевидно, что вы должны быть осторожны, если используете аргументы по умолчанию.

Удачи вам!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top