MyTetra Share
Делитесь знаниями!
Ремонт наушников Sennheiser formulapro.ru/remont-mikrofonov-i-radiosistem/.
Приведение типов в C++. Терминология, динамический полиморфизм
01.04.2016
23:35
Текстовые метки: приведение, типы, C++, термины, cast, upcast, downcast, динамический полиморфизм
Раздел: Компьютер - Программирование - Язык C++

Если происходит приведение типа-наследника к одному из базовых типов, то это называется upcast. При таком приведении использование методов вида static_cast/dynamic_cast не требуется.


Обратное действие, когда происходит приведение базового типа к типу-наследнику, называется downcast. При таком приведении явный вызов методов xxx_cast обязателен.


При downcast вопрос только в том, какой каст применить. Быстрее - static_cast, но программист должен точно знать, что указатель/ссылка указывает на объект конкретного типа. Если программист ошибется - в рантайме может произойти все, что угодно. Если же программист не может знать, на что указывает указатель (например, метод возвращает объекты разных производных типов) - придется использовать dynamic_cast, но он работает медленнее, ибо использует механизм RTTI.


Пример кода:


// Объект Qt-класса QAbstractItemModel

QAbstractItemModel *base;


// Объект класса, унаследованного от QAbstractItemModel

TreeModel *child = new TreeModel;


// Upcast

base = child; // так можно (ибо child содержит все данные для base и даже больше)


// Downcast

child = base; // так, без преобразования, нельзя (base не имеет всех данных для child)


Еще один пример кода, демонстрирующий, что в памяти разворачивается объект производного класса, и указательна этот объект свободно запоминается в указателе с типом базового класса. По этому указателю к производному классу разрешен только интерфейс базового класса. Тем не менее вся структура произвольного класса хранит в себе дополнительные данные, которые недоступны по ссылке на базовый класс.


Важно, что тем не менее, конструктор и деструктор производного класса вызываются. Конструктор вызывается потому, что командоц "new Derv" все-таки создается объект класса Derv, хоть указательна него и запоминается в указатель с типом базового класса. Деструктор вызывается потому, что у базового класса деструктор объявлен как виртуальные, и деструктор производного класса его переопределяет.


class Base

{

public:

virtual ~Base() { cout << "Base удален\n"; }

};


class Derv: public Base

{

public:

int *p;


Derv()

{

cout << "Derv - создается массив в куче\n";

p=new int[10];

}


~Derv()

{

cout << "Derv - удаляется массив в куче\n";

delete[] p;

}


void anyMethod()

{

cout << "Derv - anyMethod\n";

}

};


int main()

{

Base *pBase = new Derv;

// pBase->anyMethod(); // Будет ошибка компиляции

delete pBase;

return 0;

}


Так же в этом разделе:
 
MyTetra Share v.0.52
Яндекс индекс цитирования