Мне было интересно , как можно делать полиморфизм со ссылками, а не с указателями.
Для пояснения см. Следующий минимальный пример:
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
, я должен «преобразовать указатель в ссылку», разыменовав его.
Это поразило меня как немного странно, и мне было интересно, есть ли лучший (в смысле более чистый ) способ. Это только у меня?
Было бы здорово, если бы мне вообще не понадобился новый
, но при объявлении (!) B
я понятия не имею как создать экземпляр A1
(!) как A
- это прямое объявление - A1
реализовано в том же модуле компиляции, что и B
. Тем не менее, существует ли реальная необходимость в динамическом распределении памяти в этом случае? Как бы вы это сделали?
Извините за немного двоякий вопрос.
Примечание: B
огромен (и я не могу сделать из него шаблонный класс) и исчезнет области видимости именно тогда, когда программа завершается - a
маленький и заставляет два больших модуля взаимодействовать друг с другом, он будет нужен, пока живет экземпляр B
(есть только one).
Я только что понял, что, поскольку оба A
и B
фактически являются одиночными, я могу просто создать статический
экземпляр из A1
в блоке компиляции B
, избегая динамического распределения памяти (даже если бы было два B
s, они могли бы легко использовать один и тот же экземпляр A
). Честно говоря, я не отправлял это как ответ, но приму ответ, который побудил меня придумать это решение .