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;