c++ 在基类类型的向量中调用子类方法

Posted

技术标签:

【中文标题】c++ 在基类类型的向量中调用子类方法【英文标题】:c++ Call subclass method in vector of base class type 【发布时间】:2021-12-25 16:09:21 【问题描述】:

我有抽象类Currency 和几个子类,如FiatMoneyCrypto。我想将子类的所有对象存储在一个向量中,同时可以访问仅在这些子类中的方法。

我的 Currency.h 文件如下所示:

    class Currency

    public:
        virtual void to_String() = 0;
        float GetAmount();
        string GetShortname();
        void AddAmount(float);
        void RemoveAmount(float);
        virtual void UpdateRatio() =0;
        virtual float trade(bool, float, float, float, string) = 0;

    protected:
        string *name, *shortname;
        float *amount, *exchange_ratio;
;

还有我的 FiatMoney.h 文件:

    class FiatMoney : public Currency

    public:
        FiatMoney(string, string, float, float);
        ~FiatMoney();
        void to_String();
        void UpdateRatio();
        float trade(bool, float, float, float, string);
        void com();
    private:

;

在那个类中,我想要这个类的附加方法,称为com()。最后我的主要功能是这样的:

vector<Currency*> Wallet;
Wallet.push_back(new FiatMoney("name", "shortname", 1.0, 1.0));
Wallet[0]->com();

此时我当然有一个错误,该类货币没有成员调用com()。我怎样才能避免这种情况?

我如何才能访问仅在子类 FiatMoney 的对象中的函数 com()?

我可以在 FiatMoney 类中拥有方法而不事先将其声明为 Currency 类的 virtual 函数吗?

这是存储不同子类对象的正确方法吗?

【问题讨论】:

显示的代码表明您知道虚函数是什么,以及它们是如何工作的,这就是您如何做到这一点的。所以,你的问题不清楚?将其定义为另一个虚拟方法? @SamVarshavchik 但我不想创建另一个虚拟方法,从那时起我需要在每个子类中声明它。我只希望在一个子类中使用这种特殊方法。 @DanielJankowski "从那以后我需要在每个子类中声明它" - 不,你不需要。您可以在基类中为其提供默认实现,并仅在您想要的一个派生类中覆盖它。只有纯虚拟(即抽象)方法需要在每个派生类中实现(如您的to_String()UpdateRatio() 方法)。虚拟方法不必是抽象的。 【参考方案1】:

我如何才能访问仅在子类 FiatMoney 的对象中的函数 com()?

您必须将 Currency* 指针类型转换为 FiatMoney* 指针,但您只能在指针实际指向有效的 FiatMoney 对象时执行此操作。

当您知道Currency* 指针指向FiatMoney 对象时,您可以在编译时使用static_cast,例如:

static_cast<FiatMoney*>(Wallet[0])->com();

否则,请在运行时使用dynamic_cast测试指向的对象类型:

FiatMoney *fm = dynamic_cast<FiatMoney*>(Wallet[0]);
if (fm) fm->com();

我可以在 FiatMoney 类中拥有方法而不事先将其声明为 Currency 类的虚函数吗?

技术上是的,尽管有些人会认为在处理多态类时这不是一个好的设计选择。

这是存储不同子类对象的正确方法吗?

技术上是的,尽管Currency 应该有一个虚拟析构函数。您必须 delete new 的对象,并且虚拟析构函数将允许您在 Currency* 指针上调用 delete 以调用派生类析构函数,而无需对指针进行类型转换。因此,您应该考虑存储智能指针,例如 std::unique_ptr,而不是原始指针,以便自动为您调用 delete

【讨论】:

以上是关于c++ 在基类类型的向量中调用子类方法的主要内容,如果未能解决你的问题,请参考以下文章

创建一个基类方法,根据调用该方法的子类实例化一个新的子类对象

在基类中创建的对象调用方法中的 PHP 类型提示

如何在基类中实现子类迭代器的统一接口?

C++多态的原因

在基类体内声明但通过派生类调用的函数的内联

java多态中父类和子类一定要有一样的方法名吗