Мне было интересно как можно сделать полиморфизм со ссылками, в отличие от указателей.
Для пояснения см. Следующий минимальный пример:
class A;
class B {
public:
A& a; ///////////////// <- #1
B();
void doStuff();
};
class A {
public:
virtual void doSmth() = 0;
};
void B::doStuff() {
a.doSmth();
}
class A1 : public A {
public:
void doSmth() {
}
};
B::B() : a(
* ////////////// <- #2
(new A1) /////////// <- #3
) {
}
Этокомпилируется и работает, но самым важным моментом здесь является то, что a
в строке #1
является ссылкой, поэтому, чтобы иметь возможность использовать его полиморфно (это фактическое слово?), как показано в строке #3
Мне нужно «преобразовать указатель в ссылку», разыменовав его.
Мне кажется, что это немного странно, и мне было интересно, есть ли лучшее (в смысле cleaner ) путь.Это только я?
Обоснование
Было бы замечательно, если бы мне вообще не понадобился new
, но при объявлении (!) B
я понятия не имею, каксоздайте экземпляр A1
(!), так как A
является предварительным объявлением - A1
реализован в том же модуле компиляции, что и B
.Тем не менее, есть ли реальная потребность в динамическом распределении памяти в этом случае?Как бы вы это сделали?
Извините за слегка двоякий вопрос.
Редактировать
Примечание: B
огромен (и я не могу сделать из него шаблонный класс)и выйдет из области действия именно тогда, когда программа завершит работу - a
мала и заставляет два больших модуля общаться друг с другом, это будет необходимо до тех пор, пока существует экземпляр B
(существует только один).
Edit 2
Я только что понял, что, поскольку и A
, и B
фактически являются одиночными, я могу просто создать static
экземпляр A1
в единице компиляцииB
, избегая динамического выделения памяти (даже если было два B
с, они могли бы легко использовать один и тот же экземпляр A
).Честно говоря, я не опубликовал это как ответ, но приму ответ, который побудил меня придумать это решение .