簡體   English   中英

在 C++ 中訪問虛擬類

[英]Accessing virtual classes in C++

我試圖理解 C++ 中的虛擬類。 Wikipedia 中,我找到了這個例子:

#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

更新:

我理解這些問題,但我發現它作為嵌套接口很有用(更改最少):

#include <iostream>
#include <memory>

class Machine {
public:
    virtual void run() = 0;

    class Parts {
    public:
        virtual int get_wheels() = 0;
        virtual std::string get_fuel_type() = 0;
    };
};

class Car: public Machine {
public:
    void run() { 
        std::cout << "The car is running." << std::endl; 
    }

    class Parts: public 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";
        }
    };
};

int main () {
    std::shared_ptr<Machine> X = std::make_shared<Car>();
    (*X).run();
    std::shared_ptr<Machine::Parts> Y = std::make_shared<Car::Parts>();
    (*Y).get_wheels();
    return 0;
}

我沒有找到具有此功能的任何其他代碼。 我唯一想念的是可以直接從X訪問get_wheels 例如,讓我們考慮一下我的程序中有一Machine 我擁有的機器類型將被動態指定。 我想知道這台機器的輪子數,但是get_wheels方法必須在嵌套類Parts 更接近於解決這個問題的是上面的代碼,它給了我MachineMachine::Parts作為接口。

一個簡單的解決方案是讓您的汽車成為會員:

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中的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";
    }

};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM