c++ - C++:如何对同一个数据类使用不同的方法实现?
问题描述
背景: 我参与的程序的各个模块处理相同的对象组合,这些对象组合在一个聚合结构中。对对象组合施加了众所周知的不变量,并且所有模块都最大限度地尊重这些不变量。每个模块都由一个专门的团队开发,每个团队都需要他们自定义的特定于领域的方法来处理对象的组合。
示例: 为了给您一个切实的想法,想象一个序列容器类。容器的核心在所有用户中都是相同的:它由存储、大小/容量和分配器的数据成员组成。但是这些方法的集合、契约和方法体可能会有很大的不同。一个模块可以实现 std 样式的操作,另一个模块可以将所有操作实现为 nothrow 方法,而另一个模块可能坚持使用它们的私有检查迭代器;一些对性能至关重要的模块会痛苦地禁止所有复制操作,而另一个模块则完全用于制作副本……这样的要求在任何给定模块的每个特定领域都是合理的。
推测: 因此,提供一组单一的非冗余方法来满足所有客户团队的需求是不可能的——某些团队的需求是相互排斥的。只提供所有模块通常需要的那些方法是相当无用的,因为唯一的共同部分可能是析构函数。将所有方法的所有可能实现放在一起也不好:可维护性和稳定性差,接口臃肿令人困惑,大量名称冲突,大量跨模块依赖。
问题: 我有哪些选项可以让几个独立的实现对同一组数据成员进行操作?
我尝试过的事情: 到目前为止我能看到的解决方案并不是很好,而且我对其中的任何一个都不完全满意。我将在答案中列出它们,三种方法一一列出。
解决方案
我自己的问题的一个可能不太完美的解决方案:
3. 将代码置于 reinterpret_cast 的事实上定义的行为的摆布上。
// This is a standard layout class.
// It is the only class with data members;
// derived classes never append new data members.
class CoreData
{
public:
// Could be either explicit conversion function
// or implicit conversion operator.
template <typename Final>
// requires <LayoutCompatibleWithCore Final>
Final& As()
{
return reinterpret_cast<Final&>(*this);
}
protected:
~CoreData();
int m_x;
};
// No extra data members appended. No extra invariants imposed.
// This class is also a standard layout type,
// fully layout-compatible with CoreData.
class TeamA : public CoreData
{
public:
void push_back(Whatever args);
Iter begin();
};
class TeamB : public CoreData
{
public:
bool push_back(Whatever args);
X* begin();
};
//--------------------- Usage:
void ServiceOfTeamA::CallServiceOfTeamB(ServiceOfTeamB* srv)
{
TeamA d;
srv->Process(&d);
d.begin();
}
void ServiceOfTeamB::Process(CoreData* core)
{
TeamB& d = core->As<TeamB>();
d.push_back(567);
}
-但是,标准禁止此类技巧。所以我也不得不拒绝这种方法。
+如果它是合法的,它将提供三者中最好的语法,该语法清楚地显示了引用语义,具有 RAII 并且没有悲观化。
PS这种方法的无效让我失望。布局兼容性的全部意义似乎赋予了在 ABI 兼容进程或共享组件之间进行数据通信的能力。太糟糕了,它不允许在同一应用程序的各个部分之间进行数据通信......
推荐阅读
- python - Python 脚本需要多个 CTRL + C 才能停止
- python - 如何将函数(def)添加到数据集中超过一列?谁能帮帮我
- python - pip install editable 成功,但包不可导入(在没有 --editable 的情况下工作)
- c++ - 将 std::cout 与 Visual Studio 测试功能一起使用
- codeigniter-4 - 如何在 Codeigniter 4 中手动或使用 composer/npm 安装引导程序
- python - 如何在 for 循环中将“i”作为全局变量?
- python-2.7 - 如何触发所需参数的提示?
- javascript - 无法在 BigBlueButton API 中创建分组讨论室
- python - 使用 unittest.mock 测试用户输入和打印输出
- java - 为什么无法在 Java 11 中使用 URLClassloader(name, null) 加载 java.sql.Driver