/ / чи непряма передача даних за допомогою нового OK? - c ++, успадкування, new-operator, похідний клас, downcast

є неявним downcasting використанням нового OK? - C + +, спадщина, новий оператор, похідний клас, downcast

Що ви думаєте про цей фрагмент коду C ++:

Polygon* p;
if(shape=="Rectangle")
p = new Rectangle();
else if(shape=="Triangle")
p = new Triangle();
else
exit(EXIT_FAILURE);

де прямокутник і трикутник походять від багатокутника базового класу.

Ідея цього полягає в тому, що мені потрібно використовувати конкретніметоди з похідних класів, не знаючи, який клас мені потрібен до запуску програми. Чи є кращий спосіб зробити це? Він компілюється, але мені цікаво, чи називається деструктор обраного похідного класу, щоб певні змінні були належним чином звільнені.

Допоміжне запитання: чи включає операція динамічної передачі даних копію даних?

Дякую :)

EDIT:

Дякую за всі ці дуже повчальні відповіді.

Тепер скажемо метод

bool isIsosceles()

реалізується в трикутнику, але не в прямокутнику.

Тоді дзвоніть відразу

p->isIsosceles()

явно не вдалося б.

Мої перші ідеї:

Декларуйте та застосуйте isIsosceles () як віртуальний метод у полігоні базового класу як

virtual bool isIsosceles()
{
cout << "Isosceles means nothing to me." << endl;
exit(EXIT_FAILURE);
}

або використання динамічного_cast у операторі if.

Чи є один із цих варіантів гарною практикою тут?

Велике дякую

Відповіді:

1 для відповіді № 1

Буде працювати, якщо ви пам’ятаєте delete p і деструктора Polygon є virtual. Це життєво важливо.

Кращою альтернативою є загортання його в розумний покажчик.


1 для відповіді № 2

Чи неявне приховання з використанням нового ОК?

Тут не відбувається жодних "занепадів": це прямо використання поліморфної поведінки. Ваша Polygon * - покажчик на базовий клас; ваш будівельний код створює об'єкт, який абстрагує реалізацію за допомогою функцій віртуальних членів.

Він компілюється, але мені цікаво, чи називається деструктор обраного похідного класу, щоб конкретні змінні були належним чином звільнені.

За умови, що деструктор базового класу віртуальний (яким він повинен бути), звільняючи об’єкт через вказівник базового класу, зробить все правильно:

delete p;

Чи є кращий спосіб це зробити?

Ви могли б використовувати std::unique_ptr<Polygon> для автоматизації процесу видалення вашого Polygon об’єкт. Використання розумного вказівника знищить об'єкт, коли вказівник вийде за межі області.

Здійснює a dynamic_cast операція передбачає копію даних?

Я припускаю, що вам не потрібно користуватися dynamic_cast тут, тому що Polygon декларує функції віртуальних членів для всіх операцій, що цікавлять вас. Однак, коли ви dynamic_cast, копіювання даних не відбувається. Система перевіряє, чи дозволений виступ, і чи дає вам належним чином покажчик, або повертає a nullptr.


0 для відповіді № 3

Це не пригнічує. Ви фактично використовуєте тут поліморфізм, тобто створюєте об'єкт деякого похідного типу, який будете використовувати як об'єкт їх базового типу.

Ви можете це зробити, але як у всьому, що ви виділяєте з новим, використовуйте delete. Ще одна річ, що слід зазначити, що вам потрібен віртуальний деструктор Polygon, таким чином:

class Polygon {

virtual ~Polygon();
}

в іншому випадку ви закінчите нарізання об'єкта, тобто у вас будуть об’єкти "наполовину видалені".

Додаткова примітка: FYI, зрив з мовлення, використовуючи ваші заняття, виконує наступні дії:

Polygon* polygon = new Triangle();

Triangle* triangle = dynamic_cast<Triangle*>(polygon);

// Check that we effectively had a triangle under this polygon pointer
if(triangle){
//do something with the triangle
}

0 для відповіді № 4

Ідея цього полягає в тому, що мені потрібно використовувати конкретні методи з похідних класів, не знаючи, який клас мені потрібен до запуску програми.

Цей вид перемагає мета поліморфізму, що дозволяє виконувати операції БЕЗ знаючи, з яким похідним типом ти працюєш.

Чи є кращий спосіб це зробити?

Це залежить від того, що ви насправді намагаєтесьвиконати в першу чергу. Те, що ви показали, може бути реалізовано, наприклад, як частина фабрики класів. Тому ви не показали, як ви використовуєте ці об'єкти після їх створення, тому важко сказати, чи правильно ви чи ні.

Цікаво, чи називається деструктор обраного похідного класу, щоб конкретні змінні були належним чином звільнені.

Це буде лише в тому випадку, якщо ~Polygon() оголошено як virtual.

чи динамічна операція передачі даних включає копію даних?

№ А dynamic_cast просто виконує пошук під час виконання, щоб отримати вказівник на інший розділ VMT для того ж об'єкта.