Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么成员函数名查找保留在父类中?_C++_Inheritance - Fatal编程技术网

C++ 为什么成员函数名查找保留在父类中?

C++ 为什么成员函数名查找保留在父类中?,c++,inheritance,C++,Inheritance,动机,如果有帮助的话::我有径向基函数内核的结构成员函数。在数值模拟中,它们被称为1e06 x 15 x 1e05次。对于这么多的函数调用,我不想指望将设备虚拟化为内联虚拟函数。此外,结构(RBF核)已经用作更大插值类的模板参数 最小工作示例 我有一个始终相同的函数g(),我想重用它,所以我将它打包到基类中 函数g()调用派生类中不同的函数f() 我不想在运行时使用virtual函数解析函数名,因为这会产生额外的成本(我在代码中测量了它,它会产生影响)。 以下是一个例子: #include &l

动机,如果有帮助的话::我有径向基函数内核的结构成员函数。在数值模拟中,它们被称为1e06 x 15 x 1e05次。对于这么多的函数调用,我不想指望将设备虚拟化为内联虚拟函数。此外,结构(RBF核)已经用作更大插值类的模板参数

最小工作示例

我有一个始终相同的函数
g()
,我想重用它,所以我将它打包到基类中

函数
g()
调用派生类中不同的函数
f()

我不想在运行时使用
virtual
函数解析函数名,因为这会产生额外的成本(我在代码中测量了它,它会产生影响)。

以下是一个例子:

#include <iostream>

struct A 
{
    double f() const { return 0; };

    void g() const
    {
        std::cout << f() << std::endl; 
    }
};

struct B : private A
{
    using A::g; 
    double f() const { return 1; };
};

struct C : private A
{
    using A::g;
    double f() const { return 2; };
};

int main()
{
    B b; 
    C c; 

    b.g(); // Outputs 0 instead of 1 
    c.g(); // Outputs 0 instead of 2
}
#包括
结构A
{
双f()常量{return 0;};
void g()常量
{

std::cout这是的标准任务。基类需要知道对象的静态类型是什么,然后它将自己强制转换为该类型

template<typename Derived>
struct A
{
    void g() const
    {
        cout << static_cast<Derived const*>(this)->f() << endl;
    }
};

struct B : A<B>
{
    using A::g; 
    double f() const { return 1; };
};
模板
结构A
{
void g()常量
{

cout f()为了使多态性在C++中工作,首先需要使多态函数 Virtual。然后,你需要使用基类的指针或引用,如<代码> A*B=新B;。如果你想编译时多态,那么有很多方法,但是它的工作量大,代码复杂得多。(因此更难阅读、理解和维护)。如果A是一个很大的类,有点隐藏(例如从库中隐藏),这将非常令人困惑扩展它的人实现了一些随机函数,因为运气或编码标准与A中的某个匹配。A的整个行为可能会突然改变。@Paul92:如果A在库中,我在库中扩展了B,用一个成员函数将A中的函数隐藏起来,调用解析为B中的这个新函数,即exa确切地说,我希望发生什么事。:)还要记住,继承是一种单向关系。如果您在
a
中调用成员函数,那么它实际上并不知道任何可能的子类。虚拟分派是解决该问题的一种方法,它在运行时解决了这个问题。这是一个非常重要的信息,从一开始就应该在问题本身中nning。我们真的不应该像这样在评论中从你那里拖拽信息。了解你为什么想做某件事对于我们的理解以及我们将如何帮助你是非常重要的。只是问一个解决方案,而不提及它应该解决的问题,这就构成了一个问题。谢谢你回答其他部分!我可以把你的问题转过来,也许这有助于展示我的观点。通过实现B,我将A专门化为一个层次结构(当使用
virtual
时也是如此)。然后,我感到惊讶的是,当我使用
B;B.g();
时,类
A
任意重写
f()
,仅仅因为它共享
g()
及其派生类。:)为什么在语言中这个方向可以,而另一个方向不行?我希望使用最专门的(层次结构中的下层)对象。此外,如果
endl
添加到
B
,在
A;A.g()时,它如何在这些规则下打破
A
调用;
?根据这些规则,所有内容首先在
A
中找到。对于
A
,没有基,因此存在编译错误,因为名称查找在本例中没有找到任何内容。否则,将搜索其基
endl
,在
A
中找到并解析
endl
,而不是基。“B应该关心A的所有私有成员名称吗?”:如果它们是私有的,它不能也不关心。