Нужна помощь в диаграмме памяти - PullRequest
0 голосов
/ 29 декабря 2011

Я изучаю C ++.

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

   // dynamic_cast
  #include <iostream>
  #include <exception>
  using namespace std;

  class CBase { virtual void dummy() {} };
  class CDerived: public CBase { int a; };

  int main () {
    try {
     CBase * pba = new CDerived;
     CBase * pbb = new CBase;
     CDerived * pd;

     pd = dynamic_cast<CDerived*>(pba);
     if (pd==0) cout << "Null pointer on first type-cast" << endl;

     pd = dynamic_cast<CDerived*>(pbb);
     if (pd==0) cout << "Null pointer on second type-cast" << endl;

     } catch (exception& e) {cout << "Exception: " << e.what();}
     system("PAUSE");
     return 0;
     }

Может кто-нибудь, пожалуйстапомоги мне ..?

Ответы [ 2 ]

1 голос
/ 29 декабря 2011

Я не совсем уверен, что на самом деле ваш вопрос, но я предполагаю, что это о том, как работает dynamic_cast <> ().С практической точки зрения не должно иметь значения, как это реализовано внутри, тем более, что оно реализовано по-разному для разных систем.Есть книга Стэнли Липпмана («Внутри объектной модели C ++»), которая к настоящему времени немного устарела, но все же описывает эти детали достаточно хорошо, чтобы сформировать мысленный образ.Важно отметить, что использование dynamic_cast <> () не просто позволяет просматривать объект с другим типом и, возможно, с незначительными изменениями, но может включать поиск во внутреннем представлении чего-то похожего на дерево наследования.

Тем не менее, dynamic_cast (pba) примерно работает следующим образом:

  1. Получите указатель на информацию о внутреннем типе (обычно называемую "таблицей указателей виртуальных функций" или "vtbl", хотя современные реализации нене использовать таблицу указателей виртуальной функции ванили), которая идентифицирует тип.Чтобы это работало, статический тип аргумента dyanmic_cast, в данном случае «CBase», должен иметь хотя бы одну виртуальную функцию.
  2. Информация о типе в этом объекте может совпадать с целевым типом (так какэто, например, случай в вашем примере), в этом случае система вносит необходимые изменения в указатель (которые необходимы в некоторых случаях, связанных с множественным наследованием) и возвращает соответствующий указатель.
  3. В противном случае, т.е. если цельТип может быть базовым классом динамического типа объекта, система пытается найти целевой тип в базовых классах динамического типа.В случае одиночного наследования это достаточно просто, но может потребоваться немало поиска, если задействовано множественное наследование.

То есть использование dynamic_cast <> () часто создает потенциал для введенияпроблема производительности в вашей программе.Однако не используйте его там, где это необходимо, что может привести к сбою вашей программы.В общем, необходимость использования dynamic_cast <> () встречается относительно редко.Если вы часто используете dynamic_cast <> (), ваш дизайн почти наверняка имеет недостатки.

0 голосов
/ 29 декабря 2011

После pd = dynamic_cast<CDerived*>(pba); ситуация выглядит следующим образом:

pba ---> [CDerived]
          ^
pd -------'

pbb ---> [CBase]

Т.е., pba и pd указывают на один и тот же объект.Однако они по-разному набираются.

После pd = dynamic_cast<CDerived*>(pbb);, pd будет 0 (ноль), поскольку приведение неверно:

pba ---> [CDerived]

pd ----> (null)

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