I have code that's meant to manage operations on both a networked client and a server, since there is significant overlap between the two. However, there are a few functions here and there that are meant to be exclusively called by the client or server, and accidentally calling a client function on the server (or vice versa) is a significant source of bugs.
To reduce these sorts of programming errors, I'm trying to tag functions so that they'll raise a ruckus if they're misused. My current solution is a simple macro at the start of each function that calls an assert if the client or server accesses members they shouldn't. However, this runs into problems when there are multiple derived instances of classes, in that I have to tag the implementation as client or server side in EVERY child class.
What I'd like to be able to do is put a tag in the virtual member's signature in the base class, so that I only have to tag it once and not run into errors by forgetting to do it repeatedly. I've considered putting a check in a base class implementation and then referring to it with something like base::functionName, but that runs into the same issue as far as needing to manually add the function call to every implementation. Ideally, I'd be able to have parent versions of the function called automatically like default constructors do.
Does anybody know how to achieve something like this in C++? Is there an alternate approach I should be considering?
Thanks!
Another approach might be to override a different method than the one your callers actually call:
class Base {
public:
void doit(const Something &);
protected:
virtual void real_doit(const Something &);
};
class Derived: public Base {
protected:
virtual void real_doit(const Something &);
};
The implementation of Base::doit() could do the check to make sure that it's being called in the right environment, and then call the virtual real_doit() function. Derived classes would override the protected virtual function, and users of either class wouldn't be able to call the protected function.
The Base::doit() function is not virtual so that derived classes can't accidentally override the wrong one. (People can try, but hopefully they'll notice soon enough when it's not called.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With