如何重载继承的 class 中的方法,以便基础 class 看到继承的版本?
How to overload a method in an inherited class so that the base class sees the inherited version?
我想让继承的 class B
重载其基础 class、A
的成员函数 func()
。我知道当 B
的 object 访问时,将调用 B::func()
并且 A::func()
将被隐藏,除非通过 A::
或 [=23 明确引用=].
现在假设 A
有另一个方法 another_func()
,它调用 func()
。假设所有成员和继承都是public
,当然B
会继承another_func()
.
现在,如果我从 B::another_func()
调用 func()
,我希望调用 B::func()
,但是当我尝试时,会调用 A::func()
。对于给定的代码结构,有没有办法实现我正在寻找的行为?
我找到了 this,但这不是一回事。
答案 here 总的来说很有帮助,但并没有真正解决我的问题。
如果措辞令人困惑,这里是代码形式:
Header:
#include <iostream>
class A
{
public:
void func() { std::cout << "Called A::func()" << std::endl; };
void another_func() { func(); };
};
class B: public A
{
public:
void func() { std::cout << "Called B::func()" << std::endl; };
};
来源:
int main(int argc, char** argv)
{
B B_obj;
B_obj.func();
B_obj.another_func(); // I want this to call B::func?
return 0;
}
这段代码的输出是:
Called B::func()
Called A::func()
我想要的输出是:
Called B::func()
Called B::func()
显而易见的答案是直接做B::func()
而不是B::another_func()
,但我的实际情况更复杂,如果能够做类似以上。
编辑
基于 this,我尝试将 A::func
变成 virtual
方法,它按我想要的方式工作。但是,我还读到调用虚函数的成本要高得多。有没有更好的方法?
virtual
是唯一的方法(目前)。您定义 class A
时没有引用它可能派生的 类。在 class B
上,您应该定义 class A
中的函数是否应该更改并替换该函数自己的版本。唯一的办法就是make class A
允许其derived 类 改变一个方法。它是通过使该方法 virtual
.
#include <iostream>
class A
{
public:
virtual void func() { std::cout << "Called A::func()" << std::endl; };
void another_func() { func(); };
};
class B: public A
{
public:
void func() override { std::cout << "Called B::func()" << std::endl; };
};
如果碰巧您不想使用 virtual
因为它是 slowness
。想象一下在 assembly/machine-language 中从头开始实现这种行为。甚至重新设计架构。您最终会做出与 virtual
现在正在做的相同的行为。提供指向函数的成员指针,该函数可能会被派生 类.
更改
编辑:
I have also read that virtual functions are much more expensive to call.
没有 virtual
方法相当快。
来自 Bjarne Stroustrup 的 official website:
In my experience, the efficiency reason is usually misplaced fear. In C++, virtual function calls are so fast that their real-world use for a class designed with virtual functions does not to produce measurable run-time overheads compared to alternative solutions using ordinary function calls. Note that the virtual function call mechanism is typically used only when calling through a pointer or a reference.
我想让继承的 class B
重载其基础 class、A
的成员函数 func()
。我知道当 B
的 object 访问时,将调用 B::func()
并且 A::func()
将被隐藏,除非通过 A::
或 [=23 明确引用=].
现在假设 A
有另一个方法 another_func()
,它调用 func()
。假设所有成员和继承都是public
,当然B
会继承another_func()
.
现在,如果我从 B::another_func()
调用 func()
,我希望调用 B::func()
,但是当我尝试时,会调用 A::func()
。对于给定的代码结构,有没有办法实现我正在寻找的行为?
我找到了 this,但这不是一回事。
答案 here 总的来说很有帮助,但并没有真正解决我的问题。
如果措辞令人困惑,这里是代码形式:
Header:
#include <iostream>
class A
{
public:
void func() { std::cout << "Called A::func()" << std::endl; };
void another_func() { func(); };
};
class B: public A
{
public:
void func() { std::cout << "Called B::func()" << std::endl; };
};
来源:
int main(int argc, char** argv)
{
B B_obj;
B_obj.func();
B_obj.another_func(); // I want this to call B::func?
return 0;
}
这段代码的输出是:
Called B::func()
Called A::func()
我想要的输出是:
Called B::func()
Called B::func()
显而易见的答案是直接做B::func()
而不是B::another_func()
,但我的实际情况更复杂,如果能够做类似以上。
编辑
基于 this,我尝试将 A::func
变成 virtual
方法,它按我想要的方式工作。但是,我还读到调用虚函数的成本要高得多。有没有更好的方法?
virtual
是唯一的方法(目前)。您定义 class A
时没有引用它可能派生的 类。在 class B
上,您应该定义 class A
中的函数是否应该更改并替换该函数自己的版本。唯一的办法就是make class A
允许其derived 类 改变一个方法。它是通过使该方法 virtual
.
#include <iostream>
class A
{
public:
virtual void func() { std::cout << "Called A::func()" << std::endl; };
void another_func() { func(); };
};
class B: public A
{
public:
void func() override { std::cout << "Called B::func()" << std::endl; };
};
如果碰巧您不想使用 virtual
因为它是 slowness
。想象一下在 assembly/machine-language 中从头开始实现这种行为。甚至重新设计架构。您最终会做出与 virtual
现在正在做的相同的行为。提供指向函数的成员指针,该函数可能会被派生 类.
编辑:
I have also read that virtual functions are much more expensive to call.
没有 virtual
方法相当快。
来自 Bjarne Stroustrup 的 official website:
In my experience, the efficiency reason is usually misplaced fear. In C++, virtual function calls are so fast that their real-world use for a class designed with virtual functions does not to produce measurable run-time overheads compared to alternative solutions using ordinary function calls. Note that the virtual function call mechanism is typically used only when calling through a pointer or a reference.