Suppose I have three C++ classes FooA, FooB and FooC.
FooA has an member function named Hello, I want to call this function in class FooB, but I don't want class FooC be able to call it. The best way I can figure out to realize this is to declare FooB as a friend class of FooA. But as long as I do this, all FooA's private and protected members will be exposed which is quite unacceptable to me.
So, I wanna know if there is any mechanism in C++(03 or 11) better than friend class which can solve this dilemma.
And I assume it will be nice if the following syntax is possible:
class FooA
{
private friend class FooB:
void Hello();
void Hello2();
private:
void Hello3();
int m_iData;
};
class FooB
{
void fun()
{
FooA objA;
objA.Hello() // right
objA.Hello2() // right
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error
}
};
I think you can use Attorney-Client here.
In your case example should be like this
class FooA
{
private:
void Hello();
void Hello2();
void Hello3();
int m_iData;
friend class Client;
};
class Client
{
private:
static void Hello(FooA& obj)
{
obj.Hello();
}
static void Hello2(FooA& obj)
{
obj.Hello2();
}
friend class FooB;
};
class FooB
{
void fun()
{
FooA objA;
Client::Hello(objA); // right
Client::Hello2(objA); // right
//objA.Hello3() // compile error
//ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
/*FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error*/
}
};
There's nothing to make a class a friend of one specific function, but you can make FooB a friend of a "key" class with private constructor, and then have FooA::Hello take that class as an ignored parameter. FooC will be unable to provide the parameter and hence can't call Hello:
Is this key-oriented access-protection pattern a known idiom?
You can partially expose a class's interfaces to a specified client by inherit it from an interface class.
class FooA_for_FooB
{
public:
virtual void Hello() = 0;
virtual void Hello2() = 0;
};
class FooA : public FooA_for_FooB
{
private: /* make them private */
void Hello() override;
void Hello2() override;
private:
void Hello3();
int m_iData;
};
class FooB
{
void fun()
{
FooA objA;
FooA_for_FooB &r = objA;
r.Hello() // right
r.Hello2() // right
objA.Hello3() // compile error
objA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
objA.m_iData = 0; // compile error
}
};
Here access control is enhanced by the base class FooA_for_FooB. By a reference of type FooA_for_FooB, FooB can access the members defined within FooA_for_FooB. However, FooC cannot access those members since they have been override as private members in FooA. Your purpose can be achieved by not using the type FooA_for_FooB within FooC, or any other places except FooB, which can be kept without paying much attention.
This approach needs no friend, making things simple.
A similar thing can be done by making everything private in a base class, and selectively wrap-and-expose some of the members as public in the derived class. This approach may sometimes require ugly downcast, though. (Because the base class will become the "currency" among the whole program.)
No, and this is not really a limitation. To my mind, the limitation is that friend — a blunt weapon for hacking around design flaws — exists in the first place.
Your class FooA has no business knowing about FooB and FooC and "which one should be able to use it". It should have a public interface, and not care who can use it. That's the point of the interface! Calling functions within that interface should always leave the FooA in a nice, safe, happy, consistent state.
And if your concern is that you might accidentally use the FooA interface from somewhere you didn't mean to, well, simply don't do that; C++ is not a language suited to protecting against these kinds of user errors. Your test coverage should suffice in this case.
Strictly speaking, I'm sure you can obtain the functionality you're after with some ghastly complicated "design pattern" but, honestly, I wouldn't bother.
If this is a problem for the semantics of your program's design, then I politely suggest that your design has a flaw.
The safest solution is to use another class as the "go-between" for your two classes, rather than make one of them a friend. One way to do this is suggested in the answer by #ForEveR, but you can also do some searching about proxy classes and other design patterns that can apply.
You'll need inheritance. Try this:
// _ClassA.h
class _ClassA
{
friend class ClassA;
private:
//all your private methods here, accessible only from ClassA and _ClassA.
}
// ClassA.h
class ClassA: _ClassA
{
friend class ClassB;
private:
//all_your_methods
}
This way you have:
ClassB is the only one to be able to use ClassA.
ClassB cannot access _ClassA methods, that are private.
The whole idea of friend is to expose your class to a friend.
There are 2 ways you could be more specific about what you expose:
Inherit from FooA, that way only protected and public methods are exposed.
Only befriend a certain method, that way only that method will have access:
.
friend void FooB::fun();
You can hide private members in a base class, and then make FooA a child and friend of that base class (very touching).
// allows us to hide private members from friends of FooA,
// but still allows FooA itself to access them.
class PrivateFooA
{
private:
friend class FooA;
// only allow FooA to derive from this class
PrivateFooA() {};
// hidden from friends of FooA
void Hello3();
int m_iData;
};
// this class hides some of its private members from friend classes
class FooA : public PrivateFooA
{
private:
// give FooB access to private methods
friend class FooB;
void Hello();
void Hello2();
};
class FooB
{
void fun()
{
FooA objA;
objA.Hello(); // right
objA.Hello2(); // right
objA.Hello3(); // compile error
ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello(); // compile error
objA.Hello2(); // compile error
objA.Hello3(); // compile error
ojbA.m_iData = 0; // compile error
}
};
Anything you want to hide from FooB can be put into PrivateFooA (must be a private member), and everything else can be put directly into FooA. FooA will be able to access everything in PrivateFooA just like its own members.
This is more of an expansion of user3737631's answer, but I think it's worth posting because it includes the classes from the OP, the private constructor in PrivateFooA, and some additional comments that I thought would be helpful.
I had to do this recently and I didn't like the way these solutions leave a class type dangling around in the current namespace with essentially no purpose. If you REALLY do just want this functionality available to a single class then I would use a different pattern than those mentioned.
class Safety {
protected:
std::string _Text="";
public:
Safety(const std::string& initial_text) {
_Text=initial_text;
}
void Print(const std::string& test) {
std::cout<<test<<" Value: "<<_Text<<std::endl;
}
};
class SafetyManager {
protected:
// Use a nested class to provide any additional functionality to
// Safety that you want with protected level access. By declaring
// it here this code only belongs to this class. Also, this method
// doesn't require Safety to inherit from anything so you're only
// adding weight for the functionality you need when you need it.
// You need to be careful about how this class handles this object
// since it is really a Safety cast to a _Safety. You can't really
// add member data to this class but static data is ok.
class _Safety : Safety {
public:
void SetSafetyText(const std::string& new_text) {
_Text=std::string(new_text);
}
};
public:
static void SetSafetyText(Safety* obj, const std::string& new_text) {
if(obj==nullptr) throw "Bad pointer.";
_Safety& iobj=*(_Safety*)obj;
iobj.SetSafetyText(new_text);
}
};
Then in main (or anywhere else) you can't modify _Text through Safety but you can through SafetyManager (or it's descendants).
#include "Safety.h"
int main() {
Safety t("Hello World!");
t.Print("Initial");
SafetyManager::SetSafetyText(&t, "Brave New World!");
t.Print("Modified");
/*
t._Text; // not accessible
Safety::SetSafetyText(&t, "ERR");// doesn't exist
t.SetSafetyText(&t, "ERR"); // doesn't exist
_Safety _safety; // not accessible
SafetyManager::_Safety _safety; // not accessible
*/
}
Some would say that this follows better OOP practices than a friend class because it encapsulates the messy parts a little better and doesn't pass anything down the Safety chain of inheritance. You also don't need to modify the Safety class at all for this technique making it much more modular. These are probably the reasons why many newer languages allow for nested classes but almost nothing else has borrowed the friend concept even though this just adds functionality that is available only to a single class (and doesn't work if Safety is marked final or marked vital parts of it's code as private).
Related
Suppose I have three C++ classes FooA, FooB and FooC.
FooA has an member function named Hello, I want to call this function in class FooB, but I don't want class FooC be able to call it. The best way I can figure out to realize this is to declare FooB as a friend class of FooA. But as long as I do this, all FooA's private and protected members will be exposed which is quite unacceptable to me.
So, I wanna know if there is any mechanism in C++(03 or 11) better than friend class which can solve this dilemma.
And I assume it will be nice if the following syntax is possible:
class FooA
{
private friend class FooB:
void Hello();
void Hello2();
private:
void Hello3();
int m_iData;
};
class FooB
{
void fun()
{
FooA objA;
objA.Hello() // right
objA.Hello2() // right
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error
}
};
I think you can use Attorney-Client here.
In your case example should be like this
class FooA
{
private:
void Hello();
void Hello2();
void Hello3();
int m_iData;
friend class Client;
};
class Client
{
private:
static void Hello(FooA& obj)
{
obj.Hello();
}
static void Hello2(FooA& obj)
{
obj.Hello2();
}
friend class FooB;
};
class FooB
{
void fun()
{
FooA objA;
Client::Hello(objA); // right
Client::Hello2(objA); // right
//objA.Hello3() // compile error
//ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
/*FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
ojbA.m_iData = 0; // compile error*/
}
};
There's nothing to make a class a friend of one specific function, but you can make FooB a friend of a "key" class with private constructor, and then have FooA::Hello take that class as an ignored parameter. FooC will be unable to provide the parameter and hence can't call Hello:
Is this key-oriented access-protection pattern a known idiom?
You can partially expose a class's interfaces to a specified client by inherit it from an interface class.
class FooA_for_FooB
{
public:
virtual void Hello() = 0;
virtual void Hello2() = 0;
};
class FooA : public FooA_for_FooB
{
private: /* make them private */
void Hello() override;
void Hello2() override;
private:
void Hello3();
int m_iData;
};
class FooB
{
void fun()
{
FooA objA;
FooA_for_FooB &r = objA;
r.Hello() // right
r.Hello2() // right
objA.Hello3() // compile error
objA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello() // compile error
objA.Hello2() // compile error
objA.Hello3() // compile error
objA.m_iData = 0; // compile error
}
};
Here access control is enhanced by the base class FooA_for_FooB. By a reference of type FooA_for_FooB, FooB can access the members defined within FooA_for_FooB. However, FooC cannot access those members since they have been override as private members in FooA. Your purpose can be achieved by not using the type FooA_for_FooB within FooC, or any other places except FooB, which can be kept without paying much attention.
This approach needs no friend, making things simple.
A similar thing can be done by making everything private in a base class, and selectively wrap-and-expose some of the members as public in the derived class. This approach may sometimes require ugly downcast, though. (Because the base class will become the "currency" among the whole program.)
No, and this is not really a limitation. To my mind, the limitation is that friend — a blunt weapon for hacking around design flaws — exists in the first place.
Your class FooA has no business knowing about FooB and FooC and "which one should be able to use it". It should have a public interface, and not care who can use it. That's the point of the interface! Calling functions within that interface should always leave the FooA in a nice, safe, happy, consistent state.
And if your concern is that you might accidentally use the FooA interface from somewhere you didn't mean to, well, simply don't do that; C++ is not a language suited to protecting against these kinds of user errors. Your test coverage should suffice in this case.
Strictly speaking, I'm sure you can obtain the functionality you're after with some ghastly complicated "design pattern" but, honestly, I wouldn't bother.
If this is a problem for the semantics of your program's design, then I politely suggest that your design has a flaw.
The safest solution is to use another class as the "go-between" for your two classes, rather than make one of them a friend. One way to do this is suggested in the answer by #ForEveR, but you can also do some searching about proxy classes and other design patterns that can apply.
You'll need inheritance. Try this:
// _ClassA.h
class _ClassA
{
friend class ClassA;
private:
//all your private methods here, accessible only from ClassA and _ClassA.
}
// ClassA.h
class ClassA: _ClassA
{
friend class ClassB;
private:
//all_your_methods
}
This way you have:
ClassB is the only one to be able to use ClassA.
ClassB cannot access _ClassA methods, that are private.
The whole idea of friend is to expose your class to a friend.
There are 2 ways you could be more specific about what you expose:
Inherit from FooA, that way only protected and public methods are exposed.
Only befriend a certain method, that way only that method will have access:
.
friend void FooB::fun();
You can hide private members in a base class, and then make FooA a child and friend of that base class (very touching).
// allows us to hide private members from friends of FooA,
// but still allows FooA itself to access them.
class PrivateFooA
{
private:
friend class FooA;
// only allow FooA to derive from this class
PrivateFooA() {};
// hidden from friends of FooA
void Hello3();
int m_iData;
};
// this class hides some of its private members from friend classes
class FooA : public PrivateFooA
{
private:
// give FooB access to private methods
friend class FooB;
void Hello();
void Hello2();
};
class FooB
{
void fun()
{
FooA objA;
objA.Hello(); // right
objA.Hello2(); // right
objA.Hello3(); // compile error
ojbA.m_iData = 0; // compile error
}
};
class FooC
{
void fun()
{
FooA objA;
objA.Hello(); // compile error
objA.Hello2(); // compile error
objA.Hello3(); // compile error
ojbA.m_iData = 0; // compile error
}
};
Anything you want to hide from FooB can be put into PrivateFooA (must be a private member), and everything else can be put directly into FooA. FooA will be able to access everything in PrivateFooA just like its own members.
This is more of an expansion of user3737631's answer, but I think it's worth posting because it includes the classes from the OP, the private constructor in PrivateFooA, and some additional comments that I thought would be helpful.
I had to do this recently and I didn't like the way these solutions leave a class type dangling around in the current namespace with essentially no purpose. If you REALLY do just want this functionality available to a single class then I would use a different pattern than those mentioned.
class Safety {
protected:
std::string _Text="";
public:
Safety(const std::string& initial_text) {
_Text=initial_text;
}
void Print(const std::string& test) {
std::cout<<test<<" Value: "<<_Text<<std::endl;
}
};
class SafetyManager {
protected:
// Use a nested class to provide any additional functionality to
// Safety that you want with protected level access. By declaring
// it here this code only belongs to this class. Also, this method
// doesn't require Safety to inherit from anything so you're only
// adding weight for the functionality you need when you need it.
// You need to be careful about how this class handles this object
// since it is really a Safety cast to a _Safety. You can't really
// add member data to this class but static data is ok.
class _Safety : Safety {
public:
void SetSafetyText(const std::string& new_text) {
_Text=std::string(new_text);
}
};
public:
static void SetSafetyText(Safety* obj, const std::string& new_text) {
if(obj==nullptr) throw "Bad pointer.";
_Safety& iobj=*(_Safety*)obj;
iobj.SetSafetyText(new_text);
}
};
Then in main (or anywhere else) you can't modify _Text through Safety but you can through SafetyManager (or it's descendants).
#include "Safety.h"
int main() {
Safety t("Hello World!");
t.Print("Initial");
SafetyManager::SetSafetyText(&t, "Brave New World!");
t.Print("Modified");
/*
t._Text; // not accessible
Safety::SetSafetyText(&t, "ERR");// doesn't exist
t.SetSafetyText(&t, "ERR"); // doesn't exist
_Safety _safety; // not accessible
SafetyManager::_Safety _safety; // not accessible
*/
}
Some would say that this follows better OOP practices than a friend class because it encapsulates the messy parts a little better and doesn't pass anything down the Safety chain of inheritance. You also don't need to modify the Safety class at all for this technique making it much more modular. These are probably the reasons why many newer languages allow for nested classes but almost nothing else has borrowed the friend concept even though this just adds functionality that is available only to a single class (and doesn't work if Safety is marked final or marked vital parts of it's code as private).
A nested class Foo::Utility has access to another nested class Foo::Container even if the later is private. I am trying to extend this access to a polymorphic version UtilityPrint of Foo::Utility without success:
class Foo {
private:
class Container {};
public:
class Utility {
public:
virtual void action(Container &) = 0;
// works even if Container is private
};
Container container;
Utility * utility;
Foo(Utility * utility): container(), utility(utility) {};
void performAction() {
utility -> action(container);
}
};
// polymorphic nested class
// failed attempt
class UtilityPrint : Foo::Utility {
public:
virtual void action(Foo::Container &) {
/* Implementation */
// this does not work, because Foo::Container is private
}
};
Is there a correct way to achieve this, or is this a bad idea to begin with?
The error message I get is this:
error: ‘class Foo::Container’ is private
class Container {};
^
error: within this context
virtual void action(Foo::Container &) {
Also, Here is my reason for using this somewhat weird design:
I wanted a container and a polymorphic utility that does things to both the container and Foo. Since both container and utility would only be used within the context of Foo, I put the two classes into Foo.
EDIT: I can wrap the derived Utility in a derived Foo, and the code compiles:
class Foo {
protected:
class Container {};
public:
class Utility {
public:
virtual void action(Container &) = 0;
};
Container container;
Utility * utility;
Foo(Utility * utility): container(), utility(utility) {};
void performAction() {
utility -> action(container);
}
};
class FooPrint : public Foo {
public:
class Utility : Foo::Utility {
public:
virtual void action(Foo::Container &) {
/* Implementation */
}
};
};
This however introduces a wrapper class FooPrint which exists only for syntactic reasons and is (being a derived class!) never meant to be instantiated. I don't like this approach for this reason, but I can be very wrong on this regard.
Access is not inherited. This is more often brought up when discussing friends, but it applies here as well.
First, let's look at why Foo::Utility::action can access the private class Foo::Container. Actually, it's right there in the names. The Foo::Container can only be accessed by members of Foo, and members of Foo can be recognized when you write out their qualified names and that name starts with "Foo::".
In contrast, UtilityPrint is not a member of Foo. (In fact, it would be a huge security violation if someone could simply say "oh, yeah, I'm a member too!" and get access to your private information.) So while UtilityPrint has (protected) access to Foo::Utility, it does not have access to everything to which Foo::Utility has access.
If Foo::Utility desires to extend its access to classes derived from it, it would need to explicitly do so. One way to do this is by creating an alias.
class Utility {
protected:
using Container = Foo::Container; // Derived classes can access this.
public:
virtual void action(Container &) = 0;
virtual ~Utility() {} // <-- remember to properly support polymorphism
};
That still leaves open the question of whether or not this is good design. I would consider this a warning flag that something might be off, but not conclusively so. The question does not have enough context for me to make this sort of call. I would just give you the guideline that if you feel like you are circumventing a lot of language features (like private access), then maybe the design needs work.
I adopted this solution:
class Foo {
protected:
class Container {};
public:
class Utility {
protected:
typedef Container FooContainer;
public:
virtual void action(Container &) = 0;
};
Container container;
Utility * utility;
Foo(Utility * utility): container(), utility(utility) {};
void performAction() {
utility -> action(container);
}
};
class UtilityPrint : Foo::Utility {
public:
virtual void action(FooContainer &) {
/* implementation */
}
};
When the name FooContainer is introduced using typedef, accessibility is applied to that name only, with no regard of it actually referring to Foo::Container. This allows all derived Utility to reference Foo::Container by naming FooContainer.
I believe this also applies to using
I am currently refactoring some legacy code and would like to factorize a multiple if...elseif... statement into a series of classes implementing various strategies.
Since I have to access the original object's internals, I'm going to declare the new classes as nested classes; since nobody from the external world should access them, I'd prefer to declare them in private scope.
For the sake of exposing as few implementation details as possible, I was wondering whether it's possible to only forward-declare the base strategy class in the header file, and place all subclasses declaration in the implementation file. Code example as follows:
-- header file
class MyUglyClass
{
private:
class IStrategyBase;
IStrategyBase* sPtr;
// class ActualImplementation; // this is what I'd like to avoid
// class YetAnotherImplementation; // as above
// blah blah blah
};
-- implementation file
class MyUglyClass::IStrategyBase
{
virtual ResultType DoSomething(SomeType someParameter) = 0;
// could expose some MyUglyClass members, since
// derived classes wouldn't inherit friendship
};
class ActualImplementation: public MyUglyClass::IStrategyBase
{
ResultType DoSomething(SomeType someParameter) override
{
// Do actual work
}
}
class YetAnotherImplementation: public MyUglyClass::IStrategyBase
{
ResultType DoSomething(SomeType someParameter) override
{
// Doing something really tricky & clever for corner cases
}
}
Of course the compiler complains since IStrategyBase is not accessible; I could work around this by fwd-declaring ActualImplementation and YetAnotherImplementation into the header file together with IStrategyBase, but I'd rather avoid this, since I would need to change the header if a new strategy was needed.
I could also declare IStrategyBase in public scope, however I would prefer to keep it private to avoid other people messing with it.
Of course I'm assuming that non-fwd-declared subclasses wouldn't inherit friendship with MyUglyClass, so I would have to expose relevant data the IStrategyBase protected members.
Is there any way to achieve this I could be missing?
EDIT:
Thanks to all folks who commented, I realized that nobody could mess with IStrategyBase class even if declared in public scope, since class definition would be buried in the implementation file as well. What I'm wondering now is if I could make derived classes access internals of MyUglyClass without having to fwd declare them together with IStrategyBase. I guess answer is "no", since friendship is not inherited, but perhaps there is some more C++ perk I'm missing.
One possibility (this is not the pimpl idiom, just an accessibility hack):
class MyUglyClass
{
private:
struct Impl; // Is automatically "friend struct Impl;"
class IStrategyBase;
IStrategyBase* sPtr;
// class ActualImplementation; // this is what I'd like to avoid
// class YetAnotherImplementation; // as above
// blah blah blah
};
class MyUglyClass::IStrategyBase
{
public:
virtual int DoSomething(int someParameter) = 0;
// could expose some MyUglyClass members, since
// derived classes wouldn't inherit friendship
};
struct MyUglyClass::Impl
{
class ActualImplementation: public MyUglyClass::IStrategyBase
{
int DoSomething(int someParameter) override
{ (void) someParameter; return 1;}
};
class YetAnotherImplementation: public MyUglyClass::IStrategyBase
{
int DoSomething(int someParameter) override
{ (void) someParameter; return 2; }
};
};
int main() {}
If you want to conceal any imlementation details you can use pImpl idiom (pointer to implementation) aka Opaque pointer https://en.wikipedia.org/wiki/Opaque_pointer So you can change your code like this
-- header file
#include <memory>
class MyUglyClass
{
MyUglyClass();
~MyUglyClass(); // destructor must be only declared to avoid problems
// with deleting just forwarded inner class
private:
class Impl;
std::unique_ptr<Impl> pImpl;
};
-- implementation file
class MyUglyClass::Impl
{
class IStrategyBase;
IStrategyBase* sPtr;
class ActualImplementation; // now these classes safely hidden inside .cpp
class YetAnotherImplementation; // Nobody can reach them.
};
class MyUglyClass::Impl::IStrategyBase
{
virtual ResultType DoSomething(SomeType someParameter) = 0;
// could expose some MyUglyClass members, since
// derived classes wouldn't inherit friendship
};
class ActualImplementation: public MyUglyClass::Impl::IStrategyBase
{
ResultType DoSomething(SomeType someParameter) override
{
// Do actual work
}
};
class YetAnotherImplementation: public MyUglyClass::Impl::IStrategyBase
{
ResultType DoSomething(SomeType someParameter) override
{
// Doing something really tricky & clever for corner cases
}
};
MyUglyClass::MyUglyClass() : pImpl(new Impl()) {}
MyUglyClass::~MyUglyClass() {} // let the unique_ptr do its work
There probably is a fairly simple and straight-forward answer for this, but for some reason I can't see it.
I need to restrict calling methods from a class only to some methods implemented by derived classes of some interface.
Say I have
class A{
public:
static void foo();
};
class myInterface{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface{
public:
virtual void onlyCallFooFromHere()
{
A::foo(); //this should work
}
void otherFoo()
{
A::foo(); //i want to get a compilation error here
}
}
So I should be able to call A::foo only from the method onlyCallFooFromHere()
Is there a way to achieve this? I'm open to any suggestions, including changing the class design.
EDIT:
So... I feel there's a need to further explain the issue. I have a utility class which interacts with a database (mainly updates records) - class A.
In my interface (which represents a basic database objects) I have the virtual function updateRecord() from which I call methods from the db utility class. I want to enforce updating the database only in the updateRecord() function of all extending classes and nowhere else. I don't believe this to be a bad design choice, even if not possible. However, if indeed not possible, I would appreciate a different solution.
Change the class design - what you want is impossible.
I am unsure of what you are trying to achieve with so little details and I am unable to comment further.
[Disclaimer: this solution will stop Murphy, not Macchiavelli.]
How about:
class DatabaseQueryInterface {
public:
~virtual DatabseQueryInterface() = 0;
virtual Query compileQuery() const = 0; // or whatever
virtual ResultSet runQuery(const Query&) const = 0; // etc
};
class DatabaseUpdateInterface : public DatabaseQueryInterface {
public:
virtual Update compileUpdate() const = 0; // whatever
};
class DatabaseObject {
public:
virtual ~DatabaseObject() = 0;
protected:
virtual void queryRecord(const DatabaseQueryInterface& interface) = 0;
virtual void updateRecord(const DatabaseUpdateInterface& interface) = 0;
};
class SomeConcreteDatabaseObject : public DatabaseObject {
protected:
virtual void updateRecord(const DatabaseUpdateInterface& interface) {
// gets to use interface->compileUpdate()
}
virtual void queryRecord(const DatabaseQueryInterface& interface) {
// only gets query methods, no updates
}
};
So the basic idea is that your DatabaseObject base class squirrels away a private Query object and a private Update object and when it comes time to call the protected members of the subclass it hands off the Update interface to the updateRecord() method, and the Query interface to the queryRecord() method.
That way the natural thing for the subclasses is to use the object they are passed to talk to the database. Of course they can always resort to dirty tricks to store away a passed-in Update object and try to use it later from a query method, but frankly if they go to such lengths, they're on their own.
You could split your project into different TUs:
// A.h
class A
{
public:
static void foo();
};
// My.h
class myInterface
{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface
{
public:
virtual void onlyCallFooFromHere();
void otherFoo();
};
// My-with-A.cpp
#include "My.h"
#include "A.h"
void myImplementation::onlyCallFooFromHere() { /* use A */ }
// My-without-A.cpp
#include "My.h"
void myImplementation::otherFoo() { /* no A here */ }
You probably know this, but with inheritance, you can have public, protected, and private member access.
If a member is private in the base class, the derived cannot access it, while if that same member is protected, then the derived class can access it (while it still isn't public, so you're maintaining encapsulation).
There's no way to stop specific functions from being able to see whats available in their scope though (which is what you're asking), but you can design your base class so that the derived classes can only access specific elements of it.
This could be useful because class B could inherit from class A as protected (thus getting its protected members) while class C could inherit from the same class A as public (thus not getting access to its protected members). This will let you get some form of call availability difference at least -- between classes though, not between functions in the same class.
This could work.
class myInterface;
class A {
private:
friend class myInterface;
static void foo();
};
class myInterface {
public:
virtual void onlyCallFooFromHere() {callFoo();}
protected:
void callFoo() {A::foo();}
};
Though at this point I think I'd just make A::foo a static of myInterface. The concerns aren't really separate anymore.
class myInterface {
protected:
static void foo();
};
Is there a reason foo is in A?
I have a class with a protected method Zig::punt() and I only want it to be accessible to the class "Avocado". In C++, you'll normally do this using the "friend Avocado" specifier, but this will cause all of the other variables to become accessible to "Avocado" class; I don't want this because this breaks encapsulation.
Is what I want impossible, or does there already exist an obscure trick out there that I can use to achieve what I want? Or possibly alternative class design patterns that'll achieve the same thing?
Thanks in advance for any ideas!
Here's an ugly yet working trick:
class AvocadoFriender {
protected:
virtual void punt() = 0;
friend class Avocado;
}
class Zig : public AvocadoFriender {
...
protected:
void punt();
}
Basically you add a mixin class that exposes only the part of the interface that you want to Avocado. We take advantage of the fact that by inheriting a class that is befriended to Avocado you don't expose anything more except what was exposed originally.
I personally like the Key pattern.
class WannaBeFriend { /**/ };
class WannaBeFriendKey: boost::noncopyable
{
friend class WannaBeFriend;
WannaBeFriendKey () {}
};
And now:
class LimitedAccess
{
public:
Item& accessItem(const WannaBeFriendKey&) { return mItem; }
private:
Item mItem;
Item mOtherItem;
};
I really like this solution because:
you only need a forward declaration (like for friendship)
you don't have the full access granted by friendship, instead only a limited access is granted, under the full control of the class writer
moreover it's perfectly clear what can be accessed and from whom, thus easing debugging
this access can be granted to child classes of WannaBeFriend: it only needs exposing a protected: static const WannaBeFriend& Key(); (may or may not apply)
And of course, it's very likely that the compiler will optimize the passing of this reference since it does not serve any purpose, so it does not corrupt the design nor add unnecessary temporaries :)
You can add a proxy to the Zig class
class Foo
{
private:
int m_x, m_y;
public:
class Bar
{
friend class Baz;
int& x(Foo& blubb)
{
return blubb.m_x;
}
};
friend class Bar;
};
class Baz
{
public:
void grml(Foo& f)
{
Foo::Bar b;
// Yes, this looks awful
b.x(f) = 42;
}
};
void z()
{
Foo f;
Baz b;
b.grml(f);
}