C++ 基类中的重载方法,默认为成员变量

C++ 基类中的重载方法,默认为成员变量,c++,overloading,overriding,C++,Overloading,Overriding,我的班级结构如下: class Base { public: void setDefault( uint8_t my_default ) { m_default = my_default; } void method( uint8_t * subject ) { method( subject, m_default ); } virtual void method( uint8_t * subject, uint8_t parameter

我的班级结构如下:

class Base {
    public:
        void setDefault( uint8_t my_default ) { m_default = my_default; }

        void method( uint8_t * subject ) { method( subject, m_default ); }
        virtual void method( uint8_t * subject, uint8_t parameter ) =0;

    protected:
        uint8_t m_default;
};

class Derived1 : public Base {
    public:
        void method ( uint8_t * subject, uint8_t parameter ) { /* do something to subject */ }
};

class Derived2 : public Base {
    public:  
        void method ( uint8_t * subject, uint8_t parameter ) { /* do something different to subject */ }
};
我希望能够对从
Base
派生的类的任何实例调用
method(…)
,该实例将使用成员变量作为默认参数调用派生类中定义的方法

从我在别处读到的关于堆栈溢出的内容来看,重写必须具有相同的签名,这就是它无法编译的原因

这种方法是否存在潜在的歧义

我可以用两种方法来解决这个问题:

  • 为每个派生类声明一个默认的
    方法(void)
    ,但这看起来不是很枯燥
  • 为默认方法使用不同的名称(例如,
    defaultMethod(uint8\u t*subject)
    ),但我觉得这会降低我的类的直观性
  • 有没有更好的办法


    下面是一个完整的示例,它不会编译(Arduino IDE 1.7.9):

    产生的错误是:

    over-ride-load.ino: In function 'void loop()':
    over-ride-load.ino:39:29: error: no matching function for call to 'Derived1::method(uint8_t*)'
    over-ride-load.ino:39:29: note: candidate is:
    over-ride-load.ino:14:12: note: virtual void Derived1::method(uint8_t*, uint8_t)
    over-ride-load.ino:14:12: note:   candidate expects 2 arguments, 1 provided
    Error compiling.
    
    从我在别处读到的关于堆栈溢出的内容来看,重写必须具有相同的签名,这就是它无法编译的原因

    它将编译(如果您修复了语法错误)。它将被编译,因为覆盖具有相同的签名:

    virtual void method (uint8_t * subject, uint8_t parameter ) =0;
    

            void method( uint8_t * subject, uint8_t parameter )
    
    另一方面,选择2。(支持超载的不同名称)听起来仍然很吸引人。重载有时会很棘手、令人困惑且违反直觉


    然而,即使您的示例是正确的,您可能会发现以下内容不起作用,这可能违反直觉:

    uint8_t b;
    Derived2 d2;
    d2.method(&b);
    
    这是因为重载解析是如何工作的。您建议的选项2。琐碎地解决了这个问题,这就是为什么我建议你这么做。在父级中调用该方法的其他方法:

    • 调用
      d2.Base::method(&b)
    • 仅通过基对象指针/引用调用单参数方法
    • 使用Base::method添加
      对每个派生类的声明。约翰·伯格的回答对此进行了更深入的描述

    我相信您正在寻找的是使用指令的

    您已在
    Base
    中正确地完成了所有操作。虽然使用默认参数(通常)比定义第二个函数要好,但考虑到您的需求(使用成员),这在这里是不可能的:所以您定义了第二个重载函数来修复它(并定义了它
    内联
    -kudos!)

    但是问题来自派生类。如果您没有重写虚拟函数,一切都会很好:您可以使用
    方法的两个版本。但是您必须重写它,因此您有效地“屏蔽”了
    方法(subject)的基本版本使用
    方法(主题、参数)

    您要做的是将所有
    Base
    方法
    s“升级”到各种
    派生的
    s中,以赋予它们相等的权重。怎么用?使用指令

    在每个衍生的
    定义中,输入以下代码:

    using Base::method;
    

    将所有的
    Base
    方法“升级”到
    派生的方法中,同时仍然允许覆盖单个方法。我建议你直接在每一个代码上面加上派生的 <代码>方法()/<代码>覆盖。< /P>如果你放置了副词和使用保留关键字(默认为C++>11),IL将工作正常。只需添加一个虚拟覆盖以使其更清晰,您就可以开始了。@Davidbrcz-谢谢,纠正了示例中对保留字的误用。这很有效-我现在还不能完全理解它,但我会仔细阅读它。这是用同名派生类“隐藏”基类定义的概念,以避免编译器在尝试使用派生类时抱怨选项太多。这在理论上是可行的——直到它成为阻碍。这就是为什么他们用
    发明了
    !后半部分不起作用,对不起,我原来的问题没有说清楚。我选择了使用Base::method的
    因为它给了我最满意的解决方案,尽管它使我的代码看起来有点湿。泰。
    
    using Base::method;