Когда я посмотрел на следующий пример кода, я подумал d.B::num
был такой же как b.num
но это не так. Кажется, это другая переменная, которая имеет свой собственный адрес. Когда я нажимаю кнопку запуска, я вижу каждую из трех переменных b.num
, d.num
а также d.B::num
имеет ассоциированное значение (3, 4 и 5 соответственно).
Почему это так? И что именно d.B::num
здесь, если это не так, как b.num
?
struct B {int num;};
struct D : public B {int num;};
int main() {
B b;
D d;
b.num = 3;
d.num = 4;
d.B::num = 5;
cout << b.num << endl;
cout << d.num << endl;
cout << d.B::num << endl;
return 0;
}
Есть экземпляры классов, и есть классы. Это разные вещи. Очень похоже на то, что все целые числа не имеют одно и то же значение, разные экземпляры класса не совпадают.
Когда производный класс наследует от базового класса, экземпляры производного класса имеют в себе экземпляр (на самом деле субстанция) базового класса.
Если нет пользы от virtual
Ключевое слово, эти субэкземпляры экземпляра производного класса в основном являются совершенно нормальными экземплярами базового класса. Когда вы создаете переменную-член с тем же именем в производном, что и в базе, все, что вам нужно сделать, это скрыть переменную в субстанции базы от случайного использования. Вы все еще можете получить скрытую переменную subinstances, либо обращаясь к ней через указатель или ссылку на базу, либо полностью квалифицируя ее с помощью Base::x
синтаксис.
Несмотря на вид доступа к static
переменная, Base::x
синтаксис также используется для ссылки на имена вещей в базе, которые могут быть скрыты в производных, даже если они не являются static
,
Я упоминал, что это было верно только дляvirtual
случаев. Сейчас, virtual
методы в базе могут быть переопределены в производных. Вы можете думать о virtual
методы как указатели на фактический метид, хранящийся в base: wben вы создаете производный экземпляр, он идет и изменяет базовый подобъект производного экземпляра. virtual
указатели метода указывают на методы производных. После этого, даже если у вас есть указатель на базу, вызывая virtual
Метод может вызывать производный метод.
Другое использование virtual
это когда ты наследуешь. Если вы наследуете без virtual
это похоже на то, что экземпляры базового класса объединяются в порядке, как описано в порядке наследования, в начале экземпляра. Если вы наследуете с virtual
вместо этого есть таблица смещений, в которой указано, где базовый экземпляр относится к производному объекту. Это главным образом важно в том смысле, что вы можете иметь несколько субстанций базы в данном производном без virtual
, но только один virtual
наследование.
Некоторые из вышеперечисленных действий не совсем соответствуют стандарту, а скорее то, как компилятор может реализовать стандарты в иллюстративных целях.
Кажется, у вас есть:
B[int B::num]
а также
D[int B::num, int D::num]
если ты позвонишь d.num
по умолчанию D::num
если ты позвонишь d.B::num
по умолчанию B::num