Basically I found myself today writing lots of code like below:
#define VAL_1 0
#define VAL_2 1
class A {
public:
void memberA();
void memberB();
...
void write(uin32_t address);
}
void
A::
memberA() {
this->write(VAL_1);
}
void
A::
memberB() {
this->write(VAL_2);
}
...
So basically, I have “pretty” names memberA, memberB for some task that really only does call the same function write with a different argument. The values VAL_0 and VAL_1 are not necessarily known to code using my class. Neither is the implementation detail behind memberA or memberB, although writemight be going public at some point.
Basically, now I’m repeating the same line of code this->write(...) over and over again. I’m looking for a solution that bypasses this step and calls the respective write immediately. A kind of passing on of the function arguments somewhat like a C++ constructor from a base class, possibly with matching arguments:
#define VAL_1 0
#define VAL_2 1
class A {
public:
bool memberA() : write(VAL_1);
bool memberB() : write(VAL_2);
...
bool write(uin32_t address);
}
I’m wondering whether there might be something in Boost.Bind or some clever template-coding that lets me achieve this kind or thing?
Thanks,
FRob
Without fully understanding what you are after (I got confused about the last part involving constructors), I think you might be trying a little too hard to make the syntax easier on your clients.
… how about simply:
It’s good that you are trying to establish an easier syntax, but you also have to avoid the danger of monolithism. Monolithic classes are something that I strongly believe is one of the most common mistakes in object-oriented design. Sutter goes into this in detail in
C++ Coding Standardsand on gotw: http://www.gotw.ca/gotw/084.htm.If you have a class with 100 member functions, you probably have about 80 too many.
^ Think about this statement for a while. When you have so many functions, your classes tend to become increasingly hard to manage. It also invites other developers to just keep adding more and more to your class so that its design is never finalized. The result is the never-ending class that just grows and grows with each development cycle with no end in sight. That can easily become a source of bugs, inefficiencies, constant public interface revisions, unit test breakages, and it can go against the general reuse and flexibility of your class. When you have a separate function per value you can pass to another function, you’re dangerously treading into that territory.
Trying too hard to avoid syntactical redundancy is usually a mistake. Unfortunately C++ just requires more lengthy syntax in some cases (getting much better with C++11). What you should try to optimize away is logical redundancy. Here calling write method with various values involves no logical redundancy, and the syntactical overhead is barely more than calling different functions for each value you can possibly pass to write.
If these functions do nothing more than simplify the syntax of passing various values, you have to come to the realization that you are also bloating the class’s public interface with a whole lot more functions that, if you are in a production environment, you will likely have to document and teach individually. Strive for doing more with less and I think you’ll be much better off.
Try to keep this aspect of monolithism in mind as a priority. You might even go so far as to hoist the named constants out of the class definition as non-members, like so:
There’s actually nothing wrong with this design and, in fact, it has more desirable engineering characteristics than the one where you have more class members as it’s completely decoupled from your class, making the maintenance of that class easier, its interface simpler to teach and document, and more likely to meet a state of reasonable completion.