Долгое время я воспринимал указатели, new
и delete
несколько ненужными в С++, если не иметь дело с долгоживущими объектами, причем ссылки являются более чистой альтернативой, которая лучше подходит для модели RAII. Тем не менее, я все еще не могу установить, как избежать указателей при использовании динамического полиморфизма в С++.
Предположим, что у нас есть эта класс:
class A
{
public:
virtual void a() const = 0;
};
class B : public A
{
virtual void a() const
{
std::cout << "B";
}
};
class C : public A
{
virtual void a() const
{
std::cout << "C";
}
};
void invoke(const A& obj)
{
obj.a();
}
int main()
{
B b;
invoke(b); // Prints B
}
Объект можно передать в invoke
в качестве ссылки, и нет указателей (ну, по крайней мере, с точки зрения программиста). Однако приведенный выше пример представляет собой по существу статический полиморфизм.
Если бы я хотел, чтобы тип b
зависел от чего-то другого, мне пришлось бы использовать указатели:
int main()
{
A* a;
if (something)
a = new B;
else
a = new C;
invoke(*a); // Prints B
delete a;
}
Это выглядит ужасно для меня. Конечно, я мог бы использовать умные указатели:
int main()
{
std::unique_ptr<A> a;
if (something)
a.reset(new B);
else
a.reset(new C);
invoke(*a); // Prints B
}
Но интеллектуальные указатели - это просто оболочки для указателей.
Я хотел бы знать, есть ли способ избежать этого и использовать полиморфные классы без использования указателей.