c++中的部分类
partial class in C++
我希望避免重新编译包含公共头文件的所有内容,仅仅因为类定义的私有部分发生了某些更改。我正在研究PIMPL之外的其他选项。
这是我尝试过的:
我创建了一个包含类a的库:
A_p.h包含A类的私有部分
void PrivateMethod(int i);
A.h公共头文件:
class A
{
public:
A();
virtual ~A();
// other public members
private:
#ifdef A_PRIVATE
#include "A_p.h"
#endif
};
A.cpp
#define A_PRIVATE
#include "A.h"
A::A() {}
A::~A() {}
void A::PrivateMethod(int i) { }
然后我创建了一个Win32控制台项目,其中包括公共头文件(A.h)和针对.lib文件的链接。
一切似乎都工作,但我想知道在此过程中是否有陷阱。有人能详细说明一下吗?
"Everything seems to work" - seems there is essential。你只是在经历未定义的行为。这是一个不规范的程序——一个类的定义在使用该类的编译单元之间必须是相同的。
由于这是UB,它似乎可以工作,但是尝试在私有部分声明virtual
方法,您很可能会遇到一些可见的问题。
抽象类允许你通过子类化抽象类来声明一个公共接口但拥有私有数据和函数。
这不能按照你描述的方式工作,因此在c++标准中不支持的一个关键原因是,你提议的公共声明使得不可能知道A
的大小。公共声明不显示私有数据需要多少空间。因此,只看到公共声明的代码不能执行new A
,不能为A
数组的定义分配空间,也不能对指向A
的指针进行算术运算。
还有其他问题,可以通过某种方式解决,例如指向虚函数成员的指针的位置。但是,这会导致不必要的并发症。
要创建一个抽象类,必须在该类中声明至少一个虚函数。虚函数是用= 0
定义的,而不是函数体。这表示它没有实现,因此抽象类的对象只能作为从它派生的类的子对象。
然后,在单独的私有代码中,声明并定义一个从A
派生的类B
。您将需要提供创建和销毁对象的方法,可能使用一个公共的"new"函数,该函数返回一个指向A
的指针,并通过调用一个可以看到B
声明的私有函数来工作,以及一个公共的"delete"函数,该函数接受一个指向A
的指针,并通过调用一个可以看到B
声明的私有函数来工作。
有三种方法可以隐藏这类信息:
-
仅向前声明您的类。只有当它只是通过客户端代码传递(通过指针和/或引用),并且只有在库中使用时才有效。您的库首先需要提供工厂函数或类似的返回指针/引用,客户端永远不能调用
new
或delete
-
暴露抽象基类,并再次提供工厂函数(实例化仅在库中可见的具体派生类)
使用 pimpl
我也同意你应该重新考虑那些大到需要隐藏它的类,但是如果你真的不能把它分开,这些都是你的选择。
至于如何&为什么在实践中违反了ODR:
- 库和它的客户端代码可以对实例的大小有不同的意见。这可能导致分配/回收等问题。
- 他们也可以期望不同的数据成员偏移量,虚值表布局等。
- p。出于这些目的,内联方法算作客户端代码,因为它们不会通过添加新的动态库构建来更新
- pp。较新的优化器可能能够在不知道 的情况下内联一些行外方法。
如前所述,在c++中不可能有适当的特定类,在某些情况下这实际上很烦人。继承和Pimpl模式提供了另一种选择,但是每个对象都有一个指针的开销,这在内存有限的嵌入式软件中可能会很高。
为了解决这个问题,有一个官方的"局部类"。给ISO的建议:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0309r0.pdf不幸的是,提案被拒绝了。
- 为我的 c++ 类介绍制作一个三角形分类器.我有几个问题
- 更改 C++ 中的组合分类变量
- 只有级联分类器会发出未定义的引用错误
- 分类还是划分枚举?
- 如何删除部分类?
- 使用 SVM 进行分类,使用来自 Bag of Word 的词汇构建
- 如何读取文件并将该文件分类为不同类型的数据,这些数据都存储在结构中的特定数组中
- 将svm分类器设置为HOG检测器
- 使用类型特征的部分类专用化
- 将 CRTP 与部分类专用化结合使用?
- 为什么 C++17 标准没有带来部分类模板参数扣除?
- 神经网络和图像分类
- C++17 中的部分类模板参数推导
- 如何在这两个分类的链接列表之间获得开关的位置
- QTREEWIDGET子分类,停止下降指示器显示给定有不必要的DropIndicatorPosition
- 链接的列表字符串分类问题
- 在C /OBJ-C 中运行Tensorflow分类器模型与Python的结果不同
- 如何找到分类容器的匹配元素的索引
- 在给定的整数数组中,可以找到在给定位置之间分类数组的整数之和
- 以分类方式插入节点时遇到麻烦