Я пытаюсь понять виртуальные классы в C ++. В Википедии я нашел этот пример:
#include <iostream>
class Machine {
public:
void run() { }
class Parts {
public:
virtual int get_wheels() = 0;
virtual std::string get_fuel_type() = 0;
};
};
// The inner class "Parts" of the class "Machine" may return the number of wheels the machine has.
class Car: Machine {
public:
void run() {
std::cout << "The car is running." << std::endl;
}
class Parts: Machine::Parts {
public:
int get_wheels() override {
std::cout << "A car has 4 wheels." << std::endl;
return 4;
}
std::string get_fuel_type() override {
std::cout << "A car uses gasoline for fuel." << std::endl;
return "gasoline";
}
};
};
Я могу получить количество колес автомобиля с:
Car::Parts c_p;
c_p.get_wheels();
Есть ли другой (простой) способ? Есть ли способ инстанцировать только Car car
?
Всего 2 ответа
Простое решение будет иметь членскую часть вашего автомобиля:
struct Car : Machine {
struct Parts : Machine::Parts {
int get_wheels() override {
std::cout << "A car has 4 wheels." << std::endl;
return 4;
}
std::string get_fuel_type() override {
std::cout << "A car uses gasoline for fuel." << std::endl;
return "gasoline";
}
} parts; // <---
// or declare it as a separated member:
// Parts parts;
};
Таким образом, вы можете вызывать функции-члены следующим образом:
Car car;
std::cout << car.parts.get_weels();
Нет. В сущности, экземпляр Car
не имеет ни экземпляров Car::Parts
, ни метода, который их возвращает.
Текст вокруг примера, кажется, предполагает, что есть экземпляр Machine::Parts
каким-то образом связанный с Machine
, который волшебным образом превращается в Car::Parts
in Car
. Это может иметь место в некоторых других языках, но это не так в C ++.
Гораздо более нелепый дизайн - иметь шаблон классов черт, которые специализируются на подклассах Machine
.
template <typename Machine>
struct MachineParts;
template <>
struct MachineParts<Car> {
static int get_wheels() {
std::cout << "A car has 4 wheels." << std::endl;
return 4;
}
static std::string get_fuel_type() {
std::cout << "A car uses gasoline for fuel." << std::endl;
return "gasoline";
}
};
template <>
struct MachineParts<Bicycle> {
static int get_wheels() {
std::cout << "A bike has 2 wheels." << std::endl;
return 2;
}
static std::string get_fuel_type() {
std::cout << "A bike uses muscles for fuel." << std::endl;
return "muscles";
}
};