James369
V2EX  ›  C++

由于找不到 C++版块,只能在这里问个类成员隐藏的问题。

  •  
  •   James369 · Dec 16, 2020 · 3673 views
    This topic created in 2149 days ago, the information mentioned may be changed or developed.
    很喜欢 Objective-C 语言,特别是它的分类 Category 和扩展 Extension 的能力。现在有个项目是 C++的,碰到一个小需求,就是类实现中的某些方法,想弄成私有,并且不要在.h 头文件中声明(不声明还编译报错:prototype for '类名::函数名'does not match any in class'类名')

    简单的说,就是想彻底隐藏类中的某些方法(使其在头文件不可见)。这要是在 ObjectiveC 中用 Extension 分分钟就搞定了,而且代码也不冗余,C++不知道如何做?
    17 replies  •  2020-12-16 17:03:28 +08:00
    codehz
    codehz
    Dec 16, 2020❤️1
    1
    (你可以把私有函数不做成方法*
    直接在 cpp 文件里做成普通 static 函数
    ,不要试图用两个不同的头文件,有 abi 问题
    paoqi2048
    paoqi2048
    Dec 16, 2020
    2
    /go/cpp C++版块在这里
    James369
    James369
    OP
    Dec 16, 2020
    3
    @codehz 也是个办法,算是曲线救国,要多传一个 对象指针进去。
    Aspector
    Aspector
    Dec 16, 2020
    4
    用 pointer to implementation ?再写一个 impl 类不放头文件,用一个私有成员指针指过去。
    unifier
    unifier
    Dec 16, 2020
    5
    抽一个父类出来做接口?对外只暴露父类,可能需要配合工厂模式食用?不过感觉比 1 楼的方法更复杂了
    imkerberos
    imkerberos
    Dec 16, 2020
    6
    impl 模式.
    wutiantong
    wutiantong
    Dec 16, 2020
    7
    十年前 obj-c 还没有 extension 时,我就用 impl 模式写过这种需求
    enenaaa
    enenaaa
    Dec 16, 2020
    8
    看看 qt 源码, 很多这样的写法。
    geelaw
    geelaw
    Dec 16, 2020 via iPhone
    9
    不存在这种功能,C++ 里私有成员是接口而不是实现细节,这主要体现在字段影响内存布局、友元、可以被重写的私有虚拟成员、名字解析(私有成员会参与名字解析)。

    曲线救国的思路是 pimpl 或者接口化。
    aneostart173
    aneostart173
    Dec 16, 2020
    10
    外面只暴露接口,里面在 impl 一个类,或者只提供 c api 。
    lakehylia
    lakehylia
    Dec 16, 2020
    11
    纯虚函数接口配合 createInstance 和 releaseInstance,妥妥的
    weidaizi
    weidaizi
    Dec 16, 2020
    12
    //////////////////////////////
    // foo.h
    class Foo
    {
    public:
    static Foo* newFoo();

    void Bar();
    }

    -----------------------------------------------------------

    //////////////////////////////
    // foo_impl.h
    #include "foo.h"

    class FooImpl : public Foo
    {
    public:
    void Bar();

    private:
    void Xyz();
    };

    -----------------------------------------------------------

    然后对外只暴露 foo.h 即可
    Wirbelwind
    Wirbelwind
    Dec 16, 2020
    13
    .h 和.cc 分离 想要暴露函数的写在.h 里面
    不暴露的接口直接在.cc 里面写 第一个参数是这个类,其他不变
    class A{}
    weidaizi
    weidaizi
    Dec 16, 2020
    15
    上面那个回复,忘记写 virtual 了,囧

    //////////////////////////////
    // foo.h
    class Foo
    {
    public:
    static Foo* newFoo();

    virtual void Bar();
    }

    -----------------------------------------------------------

    //////////////////////////////
    // foo_impl.h
    #include "foo.h"

    class FooImpl : public Foo
    {
    public:
    virtual void Bar() override;

    private:
    void Xyz();

    private:
    .......
    };

    -----------------------------------------------------------

    然后对外只暴露 foo.h 即可
    jimmyismagic
    jimmyismagic
    Dec 16, 2020
    16
    上面说得很清楚,暴露个父类出来,可以是纯虚类,也可以是模板类
    Wirbelwind
    Wirbelwind
    Dec 16, 2020
    17
    还有个使用 using 的办法
    不建议继承写法
    项目里面这样的写法多了之后 后期维护的人会头大 不简洁直观
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2793 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 13:47 · PVG 21:47 · LAX 05:47 · JFK 08:47
    ♥ Do have faith in what you're doing.