9

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.

bayda
  • 13,365
  • 8
  • 39
  • 48

4 Answers4

1
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.

  • Well, SafeMember makes it easy enough to wrap them. I think OP wants to avoid wrapping them _manually_. –  Mar 17 '09 at 20:47
  • Sorry, but it works with new member variable.. I've got reminder only for default constructor. – bayda Mar 17 '09 at 21:13
  • What do you mean, "it works with a new member variable"? Did you try adding the "age" member that I gave as an example? –  Mar 17 '09 at 21:16
  • Yes. And got compiler error about forgot initialization. But what about serialize method and asignment operator? – bayda Mar 17 '09 at 21:23
  • 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. –  Mar 17 '09 at 21:29
  • Thank you for trick. It is not helpfull for solve this problem in general, but will help me and other for solve other tasks. – bayda Mar 17 '09 at 21:42
1

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
  • 73,079
  • 34
  • 148
  • 203
  • 1
    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. – bayda Mar 27 '09 at 22:07
0

I think the best way to avoid this problem is cut it at the root: Don't use custom copy operator/constructor.

This may not always be possible, but in most cases I really think it is...

Johan Kotlinski
  • 25,185
  • 9
  • 78
  • 101
0

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. – bayda Mar 18 '09 at 13:21
  • 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 Mar 27 '09 at 20:56