小弟我更喜欢朴素的C式的C++,而不是java式的C++

我更喜欢朴素的C式的C++,而不是java式的C++
最近在给公司做一套3D字体渲染类。其中遇到了如何避免向用户暴露第三方类型声明的问题。

//textRenderable.h:
//textRenderable.dll接口
class DLL_API CTextLatticeCacheMgr     //点阵缓存管理类
{
     A *m_pA;    //其中A 是第三方的字体文件解析引擎
     //......
     void generateFontLattice(wchar_t uch);   //生成unicode字符的点阵坐标函数
}

//textRenderable.cpp:
#include "ThirdHeader.h"
#include "textRenderable.h"
void CTextLatticeCacheMgr::generateFontLattice(wchar_t uch)
{
    AInit(m_pA);
    //......
}
}




如果用户想使用textRenderable.dll,我不仅得提供textRenderable.h ,还必须提供ThirdHeader.h 
这样就会暴露一些不必要暴露的第三方软件细节。老大给我的建议是用前置声明,和动态创建类,大概意思就是写个类B把A包起来,在构造函数里面new 一个A,然后 把B 放在CTextLatticeCacheMgr  进行前置声明。 这种写法很普遍,但是我很少用过,毕竟在工作中使用C++ 还不到半年。不过,我现在真的厌倦了 一层又一层的封装抽象,况且CTextLatticeCacheMgr 这个类 对效率要求也很敏感。 不是担心我代码的效率吗? 现在又要我做这事,而且系统不加字体本身的帧率就低得吓人。  于是我就没听老大的。就简单地把代码写成这样

//textRenderable.h:
//textRenderable.dll接口
class DLL_API CTextLatticeCacheMgr     //点阵缓存管理类
{
     void *m_pA;    //把原本的A* 改为void *
     //......
     void generateFontLattice(wchar_t uch);   //生成unicode字符的点阵坐标函数
}

//textRenderable.cpp:
#include "ThirdHeader.h"
#include "textRenderable.h"
void CTextLatticeCacheMgr::generateFontLattice(wchar_t uch)
{
    AInit((A*)m_pA);  //强制类型转换,哈哈,这样不就避免了向用户暴露不必要的细节了吗?
    //......
}
}


自从做了C++ ,我就厌倦了 一层又一层的封装抽象。有时候真的怀疑:这些复杂的层次真的有助于维护和扩展吗?  我想,有时候,对于一些简单的问题,我们真该返璞归真,使用C的朴实的表达方式。 将毫不相干的代码堆叠在一起的编码风格固然恶劣,过分细致地封装和抽象,满眼尽是接口的互相调用,一些关联性极强的实现被拆得七零八落不一样另人懊恼? 难道不是吗? 为什么人们最终没使用ISO的 七层网络结构而 把它精简为5层,我想就是这个道理
c++ 封装 抽象

------解决方案--------------------
依我看你有个误解,把封装与C++联系了起来,似乎使用C++就必须“一层又一层的封装抽象”,无人强迫你必须这么做,况且,封装并一定会影响效率的,其实大多数封装都不影响效率的。
------解决方案--------------------
引用:
引用:个人比较倾向你们老大的说法
为什么,能说说其中的原因吗


1. 封装一层不会降低什么运行期效率
2. 你写法没问题 但后期要是换了第三方库的初始化方法,用你的写法,如果换了第三方库,并且相应的Init方法也会改变,可能导致你们发布的头文件都要变,这个是用户不希望看到的
   
------解决方案--------------------
你老大说的也没错。

封装不会影响性能的,影响运行性能的主要是多态,同步I/O,内存分配这几个点。

只要你脑子里有内联这个概念并勤劳的正确的使用它,C++和C的速度不会有太大的差距。

C++适合大项目,大到一眼望不穿的项目,这时候封装和抽象更利于项目管理,合作开发。

对于一个小模块或者小项目,用C++是非常累赘的,很容易产生楼主的想法,我非常赞同。用C堆函数,堆结构体,什么也不用考虑,写起来又简单又快,的确是C的天下。
------解决方案--------------------
有了对象之后,生活复杂多了——C++
------解决方案--------------------
我们使用任何语言开发都应该封装,抽象,分层,模块化。原则具有普偏性。
------解决方案--------------------
当项目变大,模块变化,切换,维护,添加功能,就会发现楼主的这种做法会是一种灾难。

------解决方案--------------------
dll导出类一般不建议的,如果类结构一变,调用者也要重新编
------解决方案--------------------
好像叫 pImpl idiom 吧,好像在 Meyers 的书里面看到过,记不清那本了。
------解决方案--------------------
引用:
好像叫 pImpl idiom 吧,好像在 Meyers 的书里面看到过,记不清那本了。


effective c++ 也可能是 more effective c++ 
记不清。
------解决方案--------------------
个人觉得封装是有必要的,且不说性能上没什么大的影响。假如有一天,要换三方,封装与不封装的差别就更大了,封装性越好,代码改起来越容易
------解决方案--------------------
两三万行的软件不处理好抽象关系就已经是灾难重重了,根本用不着多大。多看看开源库你会发现稍微大一点的东西即便用C写也还是要走对象封装的路子。
------解决方案--------------------
可以做成类似com的小弟我更喜欢朴素的C式的C++,而不是java式的C++
------解决方案--------------------
楼主现在用的就是pImpl idiom方法呀,也就是Bridge模式
------解决方案--------------------
引用:
可以做成类似com的

COM就不必了,感觉pimpl不采用虚函数的方式,比之com采用虚函数的方式更加便于扩展
------解决方案--------------------
有些不懂呀,你的成员变量只是一个指针,完全可以这么写

//textRenderable.h:
//textRenderable.dll接口
class A;
class DLL_API CTextLatticeCacheMgr     //点阵缓存管理类
{
     A *m_pA;    //其中A 是第三方的字体文件解析引擎
     //......
     void generateFontLattice(wchar_t uch);   //生成unicode字符的点阵坐标函数
}
 
//textRenderable.cpp:
#include "ThirdHeader.h"
#include "textRenderable.h"
void CTextLatticeCacheMgr::generateFontLattice(wchar_t uch)
{
    AInit(m_pA);