Вопрос о синтаксисе C ++ - PullRequest
       25

Вопрос о синтаксисе C ++

0 голосов
/ 14 апреля 2009

Что означает следующий синтаксис?

typedef void* hMyClass; //typedef as a handle or reference
hMyClass f = &something;
const MyClass& foo = static_cast<MyClass&>(*f);
foo.bar();

Ответы [ 5 ]

2 голосов
/ 14 апреля 2009

static_cast означает, что система на самом деле не пытается убедиться, что при преобразовании из одного ссылочного типа в другой объект, который вы преобразовываете, фактически является экземпляром целевого типа (в отличие от динамических приведений).

Следовательно, вы говорите компилятору, что вы достаточно умны, чтобы знать, что адрес, содержащийся в hMyClass и полученный из чего-то, на самом деле содержит экземпляр MyClass, и что вы берете на себя полную ответственность за непредсказуемые вещи, случиться, если вы ошибаетесь.

Какого типа ваше "что-то"? Там также может быть ошибка. Вы можете хотеть & кое-что.

1 голос
/ 14 апреля 2009

Это на самом деле не верно. Вы присваиваете значение типу, а не переменной в строке 2.

0 голосов
/ 14 апреля 2009

Трудно сказать точно, что это «значит» без дополнительного контекста. Я предполагаю, что вы работаете над чужим кодом, и отображаемые строки разбросаны по ряду функций.

Моя лучшая догадка относительно намерений кода заключается в том, что это механизм для работы со сторонним кодом / библиотеками. В C ++ распространено использование (без шаблонов) сторонних библиотек с вашими собственными типами. Если эти библиотеки нуждаются во временном хранении данных, которые вы создали и которыми владеете, вам нужен способ предоставить библиотеке доступ к вашим данным, даже если библиотека не знает о ваших типах. Одним из примеров является функция обратного вызова / события. Если библиотека будет асинхронно уведомлять вас, когда происходит событие, вам нужно дать ей указатель функции, а также определенные пользователем данные, чтобы при вызове функции вы знали, что с ней делать. Библиотеки обычно используют указатель void * для этих предоставленных пользователем данных. В C ++ обычно просто передают экземпляр объекта для предоставленных пользователем данных и затем делегируют этому объекту для обработки обратного вызова. Вот как будет выглядеть код:

// 3rd-party library API
typedef void (*PingNotifyPtr)(void*);
void NotifyOnPing(PingNotifyPtr, void* userData);
// User Code
void MyNotify(void* myData)
{
   MyClass* ptr = (MyClass*)myData;
   // do something with ptr
}
void Main()
{
   MyClass *pClass = new MyClass();
   NotifyOnPing(&MyNotify, pClass);
   // the callback is now armed with all the data it needs.
}

Многие библиотеки достигают этого, объявляя аргументы "void *". Это необработанный указатель на некоторую область памяти. В этом месте может находиться что угодно, целое число, экземпляр класса, строка и т. Д. Сторонняя библиотека удерживает этот указатель и в какой-то момент возвращает его обратно в ваш код.

3-я строка вашего примера кода берет указатель void * и приводит его к ссылке на экземпляр класса. Ссылки на C ++ похожи на указатели, за исключением того, что они не могут иметь значение NULL и используют синтаксис значения (например, с помощью оператора «.» Вместо оператора «->».) В 4-й строке вашего примера кода затем используется метод для составной экземпляр класса.

В любом случае, если все 4 строки кода являются последовательными в кодовой базе, с которой вы имеете дело, этот код означает, что кто-то не знает C ++. Вот более компактный способ сделать один и тот же код в одной строке:

((const MyClass*)something)->Foo();

или, если вы предпочитаете синтаксис значения:

(*((const MyClass*)something)).Foo();

Удачи!

0 голосов
/ 14 апреля 2009

По сути, кто-то сохранил указатель MyClass в пустом указателе, вероятно передав его в обратный вызов. Этот код, предположительно вызванный обратно, возвращает его, чтобы использовать в качестве MyClass.

Кроме того, он имеет синтаксические ошибки, как пожелает заметки.

0 голосов
/ 14 апреля 2009

void * обычно используется для универсального указателя.

В C # это будет похоже на что-то вроде:

object o = new XmlDocument();

объект o = новый список ();

Однако в C ++ обеспечивается очень мало безопасности типов. IIRC, static_cast - это то же самое, что и (cast), поскольку проверки типов во время выполнения не выполняются

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...