има ли начин да се използва enable_shard_from_this
като връзка има-а вместо връзка е-а?
No.
enable_shared_from_this
трябва да се използва като основен клас, така че безсмисленото прилагане на указание, предназначено за други ситуации, не работи в този случай.
Дори и да имаше основателна причина да искате да направите това (а няма такава), нямаше да работи. Магията, която кара базата enable_shared_from_this
да споделя собствеността с shared_ptr
, който притежава извлечения обект, работи чрез проверка за наследяване.
enable_shared_from_this
така или иначе не моделира връзка IS-A, защото няма интерфейс, дефиниран от гледна точка на виртуални функции. IS-A означава производен тип, който разширява базов интерфейс, но това не е случаят тук. A Good
Е-НЕ-A enable_shared_from_this<Good>
.
т.е. използването на наследяване не винаги предполага връзка IS-A.
- enable_shared_from_this няма виртуален деструктор
Виртуалният деструктор е без значение, освен ако не планирате да изтриете обекта чрез указател към базовия клас enable_shared_from_this
, което би било лудост. Няма причина някога да предавате Good
като указател към базовия клас enable_shared_from_this<Good>
и още по-малко причина някога да използвате delete
върху този базов указател (обикновено типът ще бъде съхранен в shared_ptr<Good>
веднага след като бъде създаден, така че бихте никога не използвайте delete
изобщо).
enable_shared_from_this
е миксин тип, а не абстрактна база. Предоставя член shared_from_this
(и скоро weak_from_this
), това е всичко. Не трябва да го използвате като абстрактна база или интерфейсен тип, нито да използвате базовия тип за достъп до полиморфно поведение на производния тип. Фактът, че изобщо няма виртуални функции, а не просто виртуален деструктор, трябва да ви говори това.
Освен това, както н.м. коментирано по-горе, деструкторът е защитен, така че не можете да го изтриете чрез базовия клас, дори ако сте опитали (защитеният деструктор е идиоматичният начин за предотвратяване на този тип злоупотреба с миксин класове, предназначени да бъдат неполиморфни базови класове).
- Деструкторът
enable_shared_from_this
унищожава *this
, което означава, че винаги трябва да е последният извикан деструктор
а? Не съм сигурен какво имате предвид, но не носи отговорност за унищожаването на нищо освен себе си и собствения си член от данни.
- Наследяването от два класа, които и двата наследяват от
enable_shared_from_this
, може да се превърне в пречка
Трябва да работи добре (въпреки че може да не получите магическото споделяне на собствеността, ако няма нито един недвусмислен базов клас, който да е специализация на enable_shared_from_this
). Стандартната библиотека на GCC имаше грешка (сега е коригирана), при която не успява да се компилира, вместо просто да не споделя собствеността, но това не е проблем с enable_shared_from_this
.
person
Jonathan Wakely
schedule
02.12.2015
enable_shared_from_this
; имаenable_shared_from_this<D>
. Това е важно. АкоA
произлиза отenable_shared_from_this<A>
иB
произлиза отenable_shared_from_this<B>
, тогава те са различни базови класове. - person Simple   schedule 02.12.2015shared_from_this
? Трябва да посочите. Не твърдя, че някоя от тези трудности е непреодолима, те просто добавят сложност към кода, който не би бил там, ако не бешеenable_shared_from_this
наследяването. - person Jonathan Mee   schedule 02.12.2015shared_from_this()
те трябва да знаят дали да извикатA::shared_from_this()
илиB::shared_from_this()
тази трудност се усложнява, акоshared_ptr
се върне. Как мога да разбера вътрешно кой типshared_ptr
повикващият е искалshared_ptr<A>
илиshared_ptr<B>
? Отново, не е непреодолимо, то просто добавя сложност. - person Jonathan Mee   schedule 02.12.2015enable_shared_from_this
или йерархията на класовете ви трябва да бъде променена, за да има един основен клас, който предоставя функционалносттаshared_from_this
. - person Jonathan Wakely   schedule 02.12.2015shared_ptr
иenable_shared_from_this
, за да знаете защо са такива, каквито са. Трябва да можете да конструиратеshared_ptr<T>
от вече съществуващT
; наличието наenable_shared_from_this<T>
като базов клас означава, че конструкторътshared_ptr<T>
може да съхраняваweak_ptr<T>
вътре вT
. - person Simple   schedule 02.12.2015*this
. Не може. 3. Ако видите пречка, моля, посочете къде точно се намира. - person n. 1.8e9-where's-my-share m.   schedule 02.12.2015enable_shared_from_this
е предназначен да бъде извлечен от и общите страхове относно наследството не трябва да бъдат фактор при вземането на решение дали да се използва по начина, по който е проектиран да бъде използван. - person Pete Becker   schedule 02.12.2015