在C 类的方法中避免代码重复
Avoiding Code Repetitions in the Methods of a C++ Class?
成像一个正在做以下事情的类
class AClass
{
AClass() : mode(0) {}
void a()
{
if (mode != 0) throw ("Error mode should be 0");
// we pass the test, so now do something
...
mode = 1;
}
void b()
{
if (mode != 1) throw("Error mode should be 1");
// we pass the test, so now do something
...
}
int mode;
};
类包含许多方法(比20个容易),对于这些方法,我们需要对模式的值进行检查,这显然是很多代码重复。此外,我们可以识别两类方法,如果模式!= 0,那些会丢下错误的方法,如果模式!= 1,那些会丢下错误的方法。如果模式!= 0)的方法谁会丢下错误,则对于方法,如果模式!= 1)?
edit :查看当前答案,我意识到我提出问题的方式,问题可能还不够清楚。我要避免的是必须在类的每种方法中呼吁函数。无论是在方法开头编写代码还是将此代码放在函数中并调用此函数不是问题。问题是我们是否可以一起避免所有这些。是否有一种技术可以帮助自动检查类方法是否有效,具体取决于某些上下文。
Aclass实际上是我项目背景下的API。A(),B()等是程序员在使用API时可以调用的一些功能,但是其中一些方法只能以某种精确的顺序调用。例如,您可以在代码中看到A()设置模式=1。因此,程序员可以执行类似的操作:
a(); // mode = 0 so it's good
b(); // mode = 1 so it's good
但是此代码需要失败(当然会汇编,但是在执行时我需要提到一个错误,以提到B()称为错误的上下文是错误的。
b(); // mode 0 so it won't work
a(); // it will compile but throw an exception
我试图看看是否有任何模式可以做到这一点,但找不到任何东西。对我来说似乎是不可能的,我相信唯一的选择是真正编写必要的代码。有人可以建议什么吗?非常感谢。
只需添加私人成员函数:
void assert_mode_0() {
assert_mode(0);
}
void assert_mode_1() {
assert_mode(1);
}
void assert_mode(int m) {
if (mode != m)
throw msg[m];
}
当然,有适当的msg
定义。
除了用专用方法实施支票(一个很好的建议)外,您还可以考虑将AClass
中的行为分解为两个不同的类,或将特定部分委托给新的一对课程。如果mode
对于一个实例不变(如示例)。
好吧,我想最简单的解决方案是定义宏观或某些内联函数:
#define checkErrorMode0(x)
if ((x) != 0) throw ("Error mode should be 0");
#define checkErrorMode1(x)
if ((x) != 1) throw ("Error mode should be 1");
// or, probably within your class
inline void checkErrorMode0(int x){
if ( x != 0 ) throw ("Error mode should be 0");
}
inline void checkErrorMode1(int x){
if ( x != 1 ) throw ("Error mode should be 1");
}
因此,您可以简单地调用需要它们的函数内部的其中一种。
,但很可能您想做的事情有一个更优雅的解决方法。
在进一步研究问题之后,似乎最接近的答案是(by nick):
尝试研究面向方面的软件开发en.wikipedia.org/wiki/aspect-oriented_software_development - nick
Wikipedia页面不容易阅读,并且不提供C 示例,因此它一开始就非常抽象,但是如果您搜索面向方面的编程和C ,则会找到带有示例的链接。
它背后的想法(这是一个非常快速的摘要)是找到一种在类中添加"服务"或"功能"的方法。可以通过使用模板在编译时添加这些服务。这就是我直观地尝试解决我的问题的一种尝试,我很高兴看到这种技术已经存在了很多年。
此文档是一个很好的参考:
面向方面的编程&克里斯托弗·迪金斯(Christopher Diggins)的C ,2004年8月1日。
我发现了这个链接,示例很有用,可以理解该概念:
使用Calum Grant的生成编程实施方面。
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 如何重写全局方法名称以在调用原始方法之前将我的代码推到前面
- 在nodejs中使用本机代码的最佳方法是什么?
- 函数从唯一代码调用正确的子类方法
- 如何启用使用另一个类的静态方法的模板函数的自动推导,从而消除冗长的调用方代码
- 有没有更好的方法来编写这个c++代码
- 终端进程终止,退出代码为:1有什么方法可以修复它吗
- 有没有一种预处理器的方法可以从调试符号中删除代码段
- C++:销毁此代码的最佳方法是什么?
- 在.cpp文件中定义方法而不是在 C++ 的 .h 文件中定义方法时,如何提高代码的性能?
- 为什么在我的代码中没有调用 g 模拟方法
- 设计许多单例代码结构的更好方法
- 两种专用方法中的相同代码
- Android 无法从本机代码调用 Java 方法 JNI
- 有什么方法可以从Visual Studio 2017中的Catch C++测试中获取代码覆盖率指标?
- C++11 中的随机数:有没有一种简单的方法可以将生成器种子放在代码的一个位置,然后在不同的函数中使用它?
- 在没有额外代码的情况下链接两个独立类的最通用方法是什么?
- QTimer timeout()方法不再在代码重组后启动