Question

is there a concept for making sure that adding members to an existing class produce some sort of error/warning in case the implementer forgot to extend methods that should handle all members?

If a class implements several methods that have to touch all elements (e.g. import/export) it's very easy to forget one or more methods to adapt. The compiler would not recognize it and the behavior would be as expected in a lot of cases (except you have the right tests of course.)

My current attempt is to test the size of the class in every method which might be forgotten silently. But of course this is not easy to read, insecure and not compiler/platform/build type independent (so I don't like it).

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();
};

the implementation might be hidden in different/large files:

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;
}

My next try would be a macro generating a matrix (member X method) which has to be filled manually in each method but this seems not very clean to me and I doubt it performs well..

Was it helpful?

Solution 2

This is just an idea to work on, not a solution.

Pack all of your members in a tuple. Write some template metaprogramming code which will apply given function to every member of a tuple. Use that template metafunction in every method which has to go through all member and make it to apply specific function for the method.

boost::mpl may be a starting point.

BUT PLEASE NOTE: this is not easy, this is advanced technique. Depending on your experience your mileage may vary.

OTHER TIPS

Is there a concept for making sure that adding members to an existing class produce some sort of error/warning in case the implementer forgot to extend methods that should handle all members?

Yes: test-driven design. That is, before altering your code, add the test that checks for the assignment of your new member(s). Then, run the tests (they should fail). Then, fix the implementation.

Unfortunately, it is something that depends on your attention as a developer so it only works if you turn it into a habit :(

In such case I used python script + clang library. Python script generate methods like import_me, export_me by parsing class definition.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top