Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.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++_C++14 - Fatal编程技术网

C++ 使用特定重载函数的声明

C++ 使用特定重载函数的声明,c++,c++14,C++,C++14,此代码 struct Foo{ void f(){ f(0); } private: void f(int){} }; struct Bar : private Foo{ using Foo::f; }; int main() { Bar b; b.f(); } 因为Foo::f(int)是private。我对Foo::f(int)不感兴趣,我只想要Foo::f(),它是public,所以我觉得应该有办法做到这一点 我可以想出

此代码

struct Foo{
    void f(){
        f(0);
    }
private:
    void f(int){}
};

struct Bar : private Foo{
    using Foo::f;
};

int main() {
    Bar b;
    b.f();
}
因为
Foo::f(int)
private
。我对
Foo::f(int)
不感兴趣,我只想要
Foo::f()
,它是
public
,所以我觉得应该有办法做到这一点

我可以想出一些变通办法:

  • Foo::f(int)
    重命名为
    Foo::p_f(int)
    ,但这是多余的,不允许
    f
  • 实现
    Bar::foo()
  • 从邀请UB的
    Foo
    继承
    public
    ly,因为
    ~Foo()
    不是
    virtual
    (也不应该是)
  • 将所有
    f
    s
    公开
    会很容易意外地破坏
    Foo
    Bar
  • 有没有一种方法可以使用publicfoo::f说
    ?或者使用一种没有相关缺点的变通方法?

    如果您的
    f(int)
    应该是
    private
    ,并且永远不会是公共API的一部分,那么您不应该关心将其重命名为
    fimpl

    struct Foo{
        void f(){
            fimpl(0);
        }
    private:
        void fimpl(int){}
    };
    
    另一方面,如果
    f(int)
    是公共API的通用版本,并且您还需要一个带有特定值的方便包装器,那么您可以使用提供默认参数并使
    f(int)
    a
    public
    成员

    struct Foo{
        void f(int = 0){}
    };
    
    最后,如果您需要几个提供特定整数值的命名函数,那么我建议重命名这些包装器

    struct Foo{
        void f(int) {} // general interface
        void sensible_name1() { f(0); }
        void sensible_name2() { f(1); } // etc.
    }
    

    您的代码当前从
    Foo
    派生为
    private
    。因此,
    Foo::f()
    Bar
    中的私有方法。您可以通过将类声明更改为
    structbar:publicfoo
    来改变这一点

    有关一些背景信息,请参阅下的“私有继承”一节。具体而言,本节解释如下:

    [w] 当类使用私有成员访问说明符从基类派生时,基类的所有公共成员和受保护成员都可以作为派生类的私有成员访问(基类的私有成员除非是友好成员,否则永远无法访问)


    基类中没有虚拟析构函数不是自动的。只有当您有一个指向基类的指针(或引用),而该基类实际上指向(或引用)一个子类实例,并且您销毁了该实例时,才会使用UB。在你展示的代码中(无可否认很简单),没有公共继承的UB。让它们具有相同的名称实际上是一个坏主意,它坏的原因包括使用声明混乱。我建议阅读“非虚拟接口”,它也有助于减少这种混乱。为什么不将
    Foo::f(int)
    作为受保护的方法呢?任何使用
    Bar
    Foo
    的代码仍然只能访问
    Foo::f(void)
    ,因此接口是一致的。另一种解决方案是从另一个类派生
    Foo
    ,比如说
    FooInterface
    。然后在
    栏中
    可以使用FooInterface::f
    @Archimaredes说
    。如果我将
    Foo::f(int)
    设置为受保护,那么
    Bar::f(int)
    将成为
    公共的
    。这是错误的@有趣的是,这个措辞有点含糊不清。考虑< <代码> bar >代码>的情况:<代码>空隙f(int)=删除;<代码>。然后因为会有冲突,规范说没有引入与
    Foo::f(int)
    重载对应的名称。第一条规则说,没有给出此名称的访问冲突。但是重载函数的最后一句话说,必须为所有名称指定一个潜在的访问冲突。我不认为这是故意的:如果Foo中的
    void f(int)
    是名称
    f
    的唯一组成部分,那么规范要求不提供访问冲突。
    f(int=0)
    本质上使
    f(int)
    公开,这不是一个好的选择。我想我必须手动标记
    private
    函数。