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

2020-12-16 15:08:18 +08:00
 James369
很喜欢 Objective-C 语言,特别是它的分类 Category 和扩展 Extension 的能力。现在有个项目是 C++的,碰到一个小需求,就是类实现中的某些方法,想弄成私有,并且不要在.h 头文件中声明(不声明还编译报错:prototype for '类名::函数名'does not match any in class'类名')

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

曲线救国的思路是 pimpl 或者接口化。
aneostart173
2020-12-16 16:13:55 +08:00
外面只暴露接口,里面在 impl 一个类,或者只提供 c api 。
lakehylia
2020-12-16 16:19:53 +08:00
纯虚函数接口配合 createInstance 和 releaseInstance,妥妥的
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
2020-12-16 16:48:18 +08:00
.h 和.cc 分离 想要暴露函数的写在.h 里面
不暴露的接口直接在.cc 里面写 第一个参数是这个类,其他不变
class A{}
Wirbelwind
2020-12-16 16:50:43 +08:00
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
2020-12-16 16:56:37 +08:00
上面说得很清楚,暴露个父类出来,可以是纯虚类,也可以是模板类
Wirbelwind
2020-12-16 17:03:28 +08:00
还有个使用 using 的办法
不建议继承写法
项目里面这样的写法多了之后 后期维护的人会头大 不简洁直观

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/736026

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX