【问题标题】:Use attribute from derived class while using method from the base class?在使用基类中的方法时使用派生类中的属性?
【发布时间】:2021-04-13 22:12:33
【问题描述】:

我有以下代码:

    #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 吗?如果是,那我为什么首先需要基类?

【问题讨论】:

  • 是的,我知道虚拟,但这不是我要找的!我不想为每个派生类创建一个方法 displaySeats。我的目标是使用具有派生类属性的基类方法。
  • virtual 方法是完成该任务的方法。但是为每个派生类创建一个方法displaySeats 并不是完成该任务的方法。
  • 成员变量不能像成员函数那样是virtual。您正在使用子类中的 seatss 遮蔽基类 seats 变量。
  • 我目前正在尝试这样做。下面的答案给出了在派生类中使用 get_seats 的好建议。

标签: c++ oop inheritance


【解决方案1】:

这也是我经常做的事情,问题是事物是如何构造的以及哪些函数可以访问哪些变量。也许你可以这样做:

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-&gt;seats。每个子类都需要定义get_seats(),但这很容易(几乎只是return seats;)。希望这是有道理的,如果没有,请告诉我!

【讨论】:

  • 我设法使它与您的第二个建议一起工作。谢谢!!!
猜你喜欢
  • 2016-04-29
  • 2016-12-25
  • 2018-10-12
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 2015-01-17
  • 1970-01-01
  • 2011-10-03
相关资源
最近更新 更多