首页 > 解决方案 > 在使用基类中的方法时使用派生类中的属性?

问题描述

我有以下代码:

    #include <map>

class vehicle {
    private:
        int id = 0;
        std::map<std::pair<int, char>, int> seats{};
    public:
        void displaySeats();
    };
        
    class Bus : public vehicle {
    private:
        std::string type = "Bus";
    public:
        std::map<std::pair<int, char>, int> seats{ {{1,'A'},0 }, {{1,'B'},0 }, {{ 1,'C' }, 0}, {{ 1,'D' }, 0 }, {{ 1,'E' }, 0 },
            {{2,'A'},0 }, {{2,'B'},0 }, {{ 2,'C' }, 0}, {{ 2,'D' }, 0 }, {{ 2,'E' }, 0 },
            {{3,'A'},0 }, {{3,'B'},0 }, {{ 3,'C' }, 0}, {{ 3,'D' }, 0 }, {{ 3,'E' }, 0 },
            {{4,'A'},0 }, {{4,'B'},0 }, {{ 4,'C' }, 0}, {{ 4,'D' }, 0 }, {{ 4,'E' }, 0 },
            {{5,'A'},0 }, {{5,'B'},0 }, {{ 5,'C' }, 0}, {{ 5,'D' }, 0 }, {{ 5,'E' }, 0 }};
    };

    class MiniVan : public vehicle {
    private:
        std::string type = "MiniVan";
    public:
        // Seats map. <int, char> represents seats id(1A 1B 1C) the <int> will be either 0 or 1, representing if the seat is taken(1) or free(0).
        std::map<std::pair<int, char>, int> seats{ {{1,'A'},0 }, {{1,'B'},0 }, {{ 1,'C' }, 0},
            {{2,'A'},0 }, {{2,'B'},0 }, {{ 2,'C' }, 0},
            {{3,'A'},0 }, {{3,'B'},0 }, {{ 3,'C' }, 0},
            {{4,'A'},0 }, {{4,'B'},0 }, {{ 4,'C' }, 0} };
    };
    void vehicle::displaySeats()
    {
        std::pair<int, char> seat{ 1, 'E'};
        int columns = 5?this->seats.count(seat)>0:3;
    
        int displayRow = 0;
        for (const auto& p : this->seats) {
            if (displayRow == columns) {
                std::cout << std::endl;
                displayRow = 0;
            }
            displayRow++;
            std::cout << p.first.first << p.first.second << "\t ";
        }
        
    };

在 main() 我有:

MiniVan testMiniVan;
testMiniVan.displaySeats();

它显示基类中的空座位地图属性。我是 C++ 新手,但在其他语言中,它采用派生类属性。我怎么解决这个问题?我必须为每个子类创建 displaySeats 吗?如果是,那么为什么我首先需要基类?

标签: c++oopinheritance

解决方案


这也是我经常做的事情,问题是事物是如何构造的以及哪些函数可以访问哪些变量。也许您可以执行以下操作:

class Vehicle {
    private:
        int id = 0;
        std::map<std::pair<int, char>, int> seats{};
    public:
        // Add a constructor that takes in the `seats` map
        Vehicle(std::map<std::pair<int, char>, int> s) : seats(std::move(s)) {}
        void displaySeats();
};

然后对于每个子类:

class MiniVan : public Vehicle {
    private:
        std::string type = "MiniVan";
    public:
        // call the parent constructor passing in the seat map
        MiniVan() : Vehicle({{1,'A'},0 }, ...}) {}
};

另一种方法是在基类上创建一个虚函数,例如:

class Vehicle {
    ...
    protected:
        ...
        const std::map<std::pair<int, char>, int>& get_seats() const = 0;
};

displaySeats函数将调用而不是直接加载this->seats。每个子类都需要定义get_seats(),但这很容易(几乎只是return seats;)。希望这是有道理的,如果没有,请告诉我!


推荐阅读