Friend-Based Interfaces
I just thought I'd put this out here to get others' opinions on the
concept. By no means do I claim to be a C++ guru (I'm really new, to
be honest), but it just struck me as a pretty neat thing when it
occurred to me.
----------
#include <iostream>
// Forward declarations
class FirstUser;
class SecondUser;
// The interfaces to be used.
class FirstInterface {
friend class FirstUser;
private:
virtual void runFirst() = 0;
};
class SecondInterface {
friend class SecondUser;
private:
virtual void runSecond() = 0;
};
// The users of those interfaces
class FirstUser {
public:
void function(FirstInterface& foo) {
foo.runFirst();
}
};
class SecondUser {
public:
void function(SecondInterface& foo) {
foo.runSecond();
}
};
// The utilizer of those interfaces
class FinalInterface : public FirstInterface, public SecondInterface {
public:
FinalInterface()
: totalCount_(0)
{}
int totalCount() {
return(totalCount_);
}
private:
// These are only accessible from classes with the proper
permissions
void runFirst() {
std::cout << "First function run" << std::endl;
++totalCount_;
}
void runSecond() {
std::cout << "Second function run" << std::endl;
++totalCount_;
}
int totalCount_;
};
int main() {
FirstUser first;
SecondUser second;
FinalInterface final;
first.function(final);
second.function(final);
std::cout << final.totalCount() << std::endl;
return(0);
}
----------
To me it seems that a setup like this would increase the time to put
together a class (if only marginally to divide up otherwise public
functions by purpose/users), but any sort of debugging would be made
significantly easier - if value X is off somewhere, the list of what
can modify it is reduced from "Everywhere that knows this class exists
and can use its public members" to "This list of classes". It would
also encourage programmers to not take the lazy way out of problems
since they don't have access to every function at every point ("I
could just put a call here to add one to that, but then I'd have to
mess up permissions...").
Overall, I see it as a stronger encapsulation, where not only can you
pinpoint what's changing private data, but what's asking for it to be
changed in the first place. Instead of trying to pinpoint a the user
of a certain member function, you can spend more time pinpointing what
that user did.
Again though, I *am* rather new at this, so I'd appreciate some
comments and feedback. Am I completely off base on this one, and if
so, how? :)