Объявление 1: Поскольку никто никогда не узнает, что объект CBobsEdit
. Вы создаете объект как MyBobsEdit
, но сразу же приводите его к MyEdit
, поэтому все вызовы методов выполняются на MyEdit
, и не возникает никаких ошибок при вызове, а само приведение также не является неоднозначным. Функциональность CBobsEdit
никогда не используется (у вас нет методов в подклассе). Он создан, но никогда не добавляется к родителю, поэтому он никогда не отображается и никогда не используется.
Объявление 2: Ну, вы вообще не используете BobsEdit
. Что, я полагаю, не то, что вы хотели.
Объявление 3: Вы можете сделать MyEdit
шаблоном, который унаследован от его аргумента шаблона, и наследовать его непосредственно от CEdit
в одном случае и от CBobsEdit
в другом случае. Эту технику часто называют «миксин». Как:
template <typename BaseEditT>
class MyEdit : public BaseEditT { ... }
К сожалению MyEdit<CEdit>
и MyEdit<CBobsEdit>
не связаны между собой. Если вы можете сохранить указатель как CEdit
(который всегда является базовым классом), вам придется определить интерфейс, реализовать этот интерфейс в MyEdit и сохранить указатель на этот интерфейс. Интерфейс должен содержать оператор приведения к CEdit&
(и CEdit const&
), и тогда вы сможете вызывать любые методы CEdit
для него. Как это:
class IMyEdit {
virtual operator CEdit &() = 0;
virtual operator CEdit const &() const = 0;
};
template <typename BaseEditT>
class MyEdit : public BaseEditT {
operator CEdit &() { return *this; }
operator CEdit const &() const { return *this; }
};
Обратите внимание, что не только код, создающий объекты, должен видеть определение шаблона MyEdit
, поэтому вы можете поместить его в отдельный файл и включать его только в том случае, если вы определите конструктор CMyUser
, чтобы избежать наказания за время компиляции.