由于找不到 C++版块,只能在这里问个类成员隐藏的问题。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
James369
V2EX    C++

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

  •  
  •   James369 2020-12-16 15:08:18 +08:00 2764 次点击
    这是一个创建于 1760 天前的主题,其中的信息可能已经有所发展或是发生改变。
    很喜欢 Objective-C 语言,特别是它的分类 Category 和扩展 Extension 的能力。现在有个项目是 C++的,碰到一个小需求,就是类实现中的某些方法,想弄成私有,并且不要在.h 头文件中声明(不声明还编译报错:prototype for '类名::函数名'does not match any in class'类名')

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

    曲线救国的思路是 pimpl 或者接口化。
    aneostart173
        10
    aneostart173  
       2020-12-16 16:13:55 +08:00
    外面只暴露接口,里面在 impl 一个类,或者只提供 c api 。
    lakehylia
        11
    lakehylia  
       2020-12-16 16:19:53 +08:00
    纯虚函数接口配合 createInstance 和 releaseInstance,妥妥的
    weidaizi
        12
    weidaizi  
       2020-12-16 16:23:06 +08:00
    //////////////////////////////
    // 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
        13
    Wirbelwind  
       2020-12-16 16:48:18 +08:00
    .h 和.cc 分离 想要暴露函数的写在.h 里面
    不暴露的接口直接在.cc 里面写 第一个参数是这个类,其他不变
    class A{}
    Wirbelwind
        14
    Wirbelwind  
       2020-12-16 16:50:43 +08:00   1
    weidaizi
        15
    weidaizi  
       2020-12-16 16:52:59 +08:00
    上面那个回复,忘记写 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
        16
    jimmyismagic  
       2020-12-16 16:56:37 +08:00
    上面说得很清楚,暴露个父类出来,可以是纯虚类,也可以是模板类
    Wirbelwind
        17
    Wirbelwind  
       2020-12-16 17:03:28 +08:00
    还有个使用 using 的办法
    不建议继承写法
    项目里面这样的写法多了之后 后期维护的人会头大 不简洁直观
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2018 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 00:02 PVG 08:02 LAX 17:02 JFK 20:02
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86