Доступ к виртуальным классам в C ++

Я пытаюсь понять виртуальные классы в 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";
    }

};

Есть идеи?

10000