Наследование атрибутов С++
Могу ли я сделать так, чтобы при вызове метода honk у Car, атрибут brand брался с Car, а не с Vehicle ?
// Base class
class Vehicle {
public:
string brand;
void honk() {
cout << brand;
}
};
// Derived class
class Car: public Vehicle {
public:
string brand = "Mustang";
};
int main() {
Car myCar;
myCar.honk(); /* "Mustang", а не пустая строка.*/
return 0;
}
Ответы (2 шт):
Все, что делает honk, выполнить в виртуальной функции_члене, а в honk просто вызвать эту функцию_член, то есть изменить поведение honk в зависимости от разновидности транспортного средства:
class Vehicle {
string brand{ "vehicle" };
public:
virtual void b() { cout << brand; }
void honk() {
b();
}
};
class Car : public Vehicle {
string brand{ "mustang" };
public:
void b() { cout << brand; }
};
int main() {
Car myCar;
myCar.honk();
return 0;
}
Но часто, как и в данном случаи, лучше не заводить еще один член в производном классе, а занести в базовом классе в защищенное или открытое поле, затем изменить значение в производном классе.
class Vehicle {
protected:
string brand{ "vehicle" };
public:
void honk() {
cout << brand;
}
};
class Car : public Vehicle {
public:
Car() { brand = "mustang"; }
};
Так можно избавиться от лишнего хранения в объектах лишнего поля и неявного указателя на таблицу виртуальных функций _ экономить и в памяти и выиграть в скорости
А надо ли вообще хранить в одном объекте две строки? Какой в этом смысл?
Написать нормальные конструкторы и проще, и понятнее. И никаких лишних накладных расходов.
// Base class
class Vehicle {
public:
Vehicle(const string& brand = ""):brand(brand){}
string brand;
void honk() {
cout << brand;
}
};
// Derived class
class Car: public Vehicle {
public:
Car():Vehicle("Mustang"){};
};
int main() {
Car myCar;
myCar.honk(); /* "Mustang", а не пустая строка.*/
return 0;
}