4

是否有一个概念可以确保将成员添加到现有类会产生某种错误/警告,以防实现者忘记扩展应该处理所有成员的方法?

如果一个类实现了几个必须接触所有元素的方法(例如导入/导出),那么很容易忘记一个或多个方法来适应。编译器不会识别它,并且在很多情况下行为会如预期的那样(当然,除非你有正确的测试。)

我目前的尝试是在每个可能被默默遗忘的方法中测试类的大小。但是,这当然不容易阅读,不安全且与编译器/平台/构建类型无关(所以我不喜欢它)。

class C
{ 
    int element1;
    int element2;
    int element3;   <--- newly added without adapting operator==()

public:

    void import_me();
    void export_me();
    bool operator== (const C&);
    void dump();
};

该实现可能隐藏在不同/大文件中:

void C::import_me(){
    assert( sizeof( *this ) == 12 ); // this is my attempt of doing this

    read_fn( element1 );
    read_fn( element2 );
    read_fn( element3 );
}

void C::export_me(){
    assert( sizeof( *this ) == 12 ); // this is my attempt of doing this

    write_fn( element1 );
    write_fn( element2 );
    write_fn( element3 );
}

/// the implementer forgot to adapt this method
bool C::operator==(const C &other) {

    assert( sizeof( *this ) == 8 );             <--- this would fail

    if( element1 != other.element1 ) return false;
    if( element2 != other.element2 ) return false;
    return true;
}

我的下一个尝试将是一个宏生成一个必须在每个方法中手动填充的矩阵(成员 X 方法),但这对我来说似乎不是很干净,我怀疑它是否表现良好..

4

3 回答 3

2

是否有一个概念可以确保将成员添加到现有类会产生某种错误/警告,以防实现者忘记扩展应该处理所有成员的方法?

是的:测试驱动设计。也就是说,在更改代码之前,添加检查新成员分配的测试。然后,运行测试(它们应该会失败)。然后,修复实现。

不幸的是,这取决于你作为开发人员的注意力,所以只有当你把它变成一种习惯时它才会起作用:(

于 2013-08-20T11:13:48.000 回答
1

这只是一个想法,而不是解决方案。

将所有成员打包成一个元组。编写一些模板元编程代码,将给定的函数应用于元组的每个成员。在必须通过所有成员的每个方法中使用该模板元功能,并使其为该方法应用特定功能。

boost::mpl 可能是一个起点。

但请注意:这并不容易,这是先进的技术。根据您的经验,您的里程可能会有所不同。

于 2013-08-20T10:39:35.763 回答
0

在这种情况下,我使用了 python 脚本 + clang 库。Python脚本通过解析类定义生成import_me、export_me等方法。

于 2013-08-20T10:38:38.403 回答