Я пытаюсь смоделировать взаимосвязь записей ресурсов DNS на C++ для моего преобразователя DNS, который я пишу. В DNS каждая запись ресурса имеет стандартную информацию, такую как время жизни записи, доменное имя, которое описывает запись, и т. д. Самое главное, что каждая запись ресурса имеет поле «rtype», которое описывает, какой тип пользовательских данных содержит запись ресурса. Я моделирую все это в базовом классе.
Код: Выделить всё
class ResourceRecord{
int rType;
...other fields and methods that are not important...
}
Для каждого типа ResourceRecord я реализую базовый класс.
Например, запись ресурса «A» содержит 32-битный IP-адрес.
Код: Выделить всё
class AResourceRecord : public ResourceRecord{
...other fields and methods that are not important...
private:
uint32_t ip;
}
Другим примером является запись ресурса «NS», которая содержит строковое имя домена.
Код: Выделить всё
class NSResourceRecord : public ResourceRecord{
...other fields and methods that are not important...
private:
string domain;
}
Сопоставитель DNS, который я создаю, знает тип записи ресурса только после того, как он прочитает буфер из ответа сети. У меня есть контейнеры, которые я использую, с типом шаблона ResourceRecord, поэтому мне не нужно создавать один контейнер для AResourceRecords, другой для NSResourceRecords и т. д. Когда я получаю ответ сети, я проверяю значение rType, а затем создаю объект подкласса ResourceRecord, основанный на нем. Затем я добавляю их в различные контейнеры ResourceRecord, которые моделируют кеш и другие вещи. Это все работает. Проблема в том, что мне нужно извлечь запись и использовать ее пользовательские данные. Например, скажем, у меня есть метод sendRequest(uint32_t ip). Если бы у меня был объект ResourceRecord из кеша, который, как я знаю, также является динамическим AResourceRecord (поскольку его поле rType из базового класса равно «A»), я не могу получить доступ к его пользовательским данным, поскольку его статический тип — ResourceRecord. Я изо всех сил пытался придумать способ добиться этого с помощью виртуальных методов. Каков наилучший способ сохранить полиморфный контейнер, сохраняя при этом возможность использовать объект базового класса в качестве производного типа, и я знаю, что это произойдет, когда придет время? Это хороший вариант использования Dynamic_cast? Т.е. было бы неплохо добавить производный объект в контейнер базового класса, а затем, когда мне понадобится определенный тип (скажем, uint32_t), сделайте следующее:
Код: Выделить всё
ResourceRecord recFromCache = getFromCache()
if(recFromCache.rType == A){
AResourceRecord aRec = dynamic_cast(recFromCache)
methodThatNeedsAResourceData(aRec.ip)
}
Как лучше всего это сделать?
Спасибо.
Подробнее здесь:
https://stackoverflow.com/questions/792 ... proper-way