tags:

views:

211

answers:

3

Almost all c++ projects have classes with copy c-tor/copy operator/serialize method etc. Which usualy doing something with all members.

But sometimes developers forgets to add new member to this functions.
Do you know any easy, not wrapp all members way which will remind developers to do something or write noop(memeber_name_) in this functions.

I tried to invent something but got fault.

PS: unit tests could prevent this problem, but I want something compile time.

+1  A: 
template<class T>
class SafeMember {
public:
    T _;    /* short name for convenience */
    SafeMember(T const& obj) : _(obj) { }
};

Used like this:

class Student {
public:
    Student(string surname, Color hairColor)
        : surname(surname)
        , hairColor(hairColor) { }

    Student(Student const& other)
        : surname(other.surname)
        , hairColor(other.hairColor) { }

    Student& operator=(Student const& other) {
        surname = other.surname;
        hairColor = other.hairColor;
        return *this;
    }

    string getSurname() const { return surname._; }

    // The foo._ syntax is better than implicit conversion because
    // it lets us call member functions, like substr in this example:
    bool isSlavic() const {return surname._.substr(surname._.size()-2)=="ev";}

    void dyeHair(Color newColor) { hairColor = newColor; }

private:
    SafeMember<string> surname;
    SafeMember<Color> hairColor;
};

Now when you add a "SafeMember<int> age" member and forget to update your copy-constructor, the compilation will helpfully fail.

And for a "no-op" hint, the developer would add an initializer like ":age(0)".

Note: this doesn't protect your operator=() or serialize() functions from bit-rot, only the constructors. Hopefully, though, this should be enough: once you see your omission from the constructors, you will probably remember to go through the other functions as well.

"not wrapp all members way".
Mykola Golubyev
Well, SafeMember makes it easy enough to wrap them. I think OP wants to avoid wrapping them _manually_.
Sorry, but it works with new member variable..I've got reminder only for default constructor.
bb
What do you mean, "it works with a new member variable"? Did you try adding the "age" member that I gave as an example?
Yes. And got compiler error about forgot initialization. But what about serialize method and asignment operator?
bb
Ah, yes. I forgot to mention... it only reminds you about the copy constructor. Then hopefully you'll also remember to update operator= and serialize() as well.
Thank you for trick.It is not helpfull for solve this problem in general, but will help me and other for solve other tasks.
bb
Well, you're welcome :)
A: 

It looks like there is no satisfying solution to your problem (Iraimbilanja solution is probably one of the best approaches, but still it's not perfect). I wonder if there are features in upcoming C++0x that will allow to solve this?

I'm continue try to discover acceptable solution:) It will be acceptable if C++0x will have some tools for solve problem. I will check C++0x draft.
bb
Maybe the compiler could check it and issue a warning that some member is not copied... but then how would you say that you don't care about some member...
Roman Plášil
+1  A: 

Add this functionality to your unit test. If your unit test covers serializaiton/deserialization (for example, by making sure deser(ser(x)) == x), failure to add members to the serialization function would fail during unit testing. The same could work for copy ctors.

It's not as ideal as compile time errors, but if you have a good unit test framework in place and you make sure that you have proper coverage, then these errors of neglect would be harder to make.

Assaf Lavie
Thanks for response. In general: unit testing - nice thing, and I thought about control with unit testing. But we can forget add member to operator== and assert( deserialize( serialize( x )) == x ) or ' y = x; assert( y == x ); will ok if we forget add member in some of used functions.
bb