Я уже некоторое время программирую в школе и работаю над своим первым крупным независимым проектом.Я обнаружил много вещей о программировании, которых я не знал прежде, и это было здорово.
Однако, все больше и больше, я чувствую, что больше не понимаю C ++ как язык, чем больше я вникаювнутрь.Я хотел бы получить некоторые из моих (неправильных) представлений о ссылках и указателях прямо перед продолжением, и я надеюсь, что вы, stackoverflow, могли бы исправить меня, если я ошибаюсь.
Заранее спасибо, и здесьмы идем!
1.При преобразовании между классами фактически преобразуется виртуальная таблица.
Пример:
class A{
public:
A() : x(0) {};
int x;
virtual void doStuff() {
cout << x <<endl;
}
};
class B : public A{
public:
B() : y(1) {};
int y;
virtual void doStuff() {
cout << y <<endl;
}
};
Если бы я преобразовал объект b типа B в A, что бы произошловнутренне виртуальная таблица b будет отброшена и заменена соответствующей виртуальной таблицей типа A, и будет вызван деструктор y, поскольку на нее больше нет ссылки.Аналогично, doStuff в b должен указывать на адрес функции A :: doStuff вместо B :: doStuff.Однако адрес, указывающий на x, останется прежним.
2.Это означает, что единственный способ воспользоваться полиморфизмом - это использовать указатели и ссылки.
Как следствие пункта 1, единственный способ использовать преимущества полиморфизма в виртуальных методах классов состоит в использовании ссылок.и указатели, потому что если мы передадим по значению, сами классы будут автоматически преобразованы в базовый класс.
Пример:
void doALotOfStuff(A a1, A a2) {
a1.doStuff();
a2.doStuff();
}
int main(){
A a;
B b;
doALotOfStuff(a,b);
return 0;
}
выведет
0
0
потому что компилятор сгенерирует код для преобразования b в A.
3.Кроме того, единственный способ воспользоваться преимуществами этого вида полиморфизма с массивами и контейнерами STL состоит в том, чтобы использовать указатели, поскольку ссылки не могут быть сохранены
Поскольку вектор не будет работать, поскольку ссылки не могут быть назначены, следуетчто если бы я хотел иметь вектор базовых классов, мне нужно было бы создать вектор указателей A, чтобы сохранить виртуальную таблицу элементов типа B.
Извините, если это был TL; DR,но это было своего рода беспокойство, когда я занимался дизайном классов для своего проекта, и я понял, что не могу просто избежать использования указателей или ссылок из-за библиотечных интерфейсов и проблем полиморфизма.