How can I reach privateMember without friend in all of the derived classes?
class parent{...}; //a virtual class
class A: public parent{...};
class B: public parent{...};
class C: public parent{...};
class D: public parent{...};
class E: public parent{...};
...
//each has a function, that want access to privateMember
class MyClass{
int privateMember;
friend parent;
//I know it doesnt't work, but this shows the best what I want
}
Leave it as is (with friend class parent) and add an accessor function to parent that A, B,... will use. It would be protected, so functions from outside the hierarchy can't use it.
class parent {
protected:
static int& getPrivate( MyClass & c ) { return c.privateMember; }
...
};
You have to do this, because friendship doesn't extend to derived classes.
You could create a getter function, that would return a privateMember:
int getPrivateMember() const { return privateMEmber; }
This must be a public method of course.
The simple answer here is to not go mucking with the internal state of other classes. Instead, use their public API. This way you never have to worry about locking yourself into an implementation AND you avoid a wide variety of potential problems with inadvertently breaking class invariants when you modify the variable.
Related
Here's what I'm trying to do:
class A
{
friend class C (and all of C's derived classes)
public:
void DoAThing() { mpMyC->DelegateResponsibility(myB); }
private:
class B
{
};
B mMyB;
C* mpMyC;
};
class C
{
// No problem here- C can see B
virtual void DelegateResponsibility(const A::B& necessaryInfo);
};
class D: public C
{
// Uh-oh- we don't inherit friendship
virtual void DelegateResonsibility(const A::B& necessaryInfo);
};
In short, I have a private nested class inside A because it's an implementation detail of A. However, I'd like to delegate some responsibilities of A to C and C's derived classes to get some polymorphic behavior. I'd like to avoid having to add a friend class line every time someone derives from C. The standard workaround given for derived friend classes is "just add a protected accessor function to your base class and override it for derived members" but that only helps access private members of class A, not privately scoped classes. Is there any way to workaround this issue?
This should work:
class C
{
typedef A::B MyB;
virtual void DelegateResponsibility(const MyB& necessaryInfo);
};
class D: public C
{
// Uh-oh- we don't inherit friendship
virtual void DelegateResonsibility(const MyB& necessaryInfo);
};
You could put your class B in a detail namespace, at file scope.
something like this:
namespace my_hidden_area {
class B {
...
}
}
It's not as strong protection as making the class nested private, of course, but it should make it clear to outsiders that they should not be messing around with B.
If you're wondering why friendship is not inheritable, see this question: Why does C++ not allow inherited friendship?
If i have two classes, for example like this
class A {
...
protected:
B* test;
aFunction();
};
class B {
...
protected:
A* test1;
public:
bFunction();
};
can I do this inside bFunction() of class B:
bFunction(){
test1->aFunction();
}
Basically, can I call a protected function of a certain class from the class that's not derived from that function?
The "point" of the protected is that only classes that are derived from the baseclass can call those functions.
If you have a good reason to do this, then make the class a friend, e.g. add friend class B; inside class A.
It is recommended to avoid such inevident mutual dependencies. A necessity to use friend functions often indicates bad architecture.
From cplusplus.com:
Private and protected members of a class cannot be accessed from
outside the same class in which they are declared. However, this rules
does not affect friends.
You can call protected and privat methods from other classes, when those are 'friends':
In your case that would be:
Class A {
...
protected:
B* test;
aFunction();
friend class B;
}
Often that is considered bad practice, but for tightly coupled classes that is ok.
Found related questions but not the exact variant so I am posting a very simple question.
A derived class inherits from a templated base, and I want to call the base function, how to do it?
template <class A>
class testBase {
public:
void insert(const A& insertType) {
// whatever
}
};
class testDerived : testBase<double> {
// whatever
};
int main() {
testDerived B;
// Compiler doesn't recognize base class insert
// How do you do this?
B.insert(1.0);
}
Need public inheritance (default is private for class):
class testDerived : public testBase<double> {
A class has a default access level of 'private'. You basically inherited 'testBase' using private inheritance so that testBase's public interface is not part of testDerived's. Simple solution:
class testDerived: public testBase<double> {...};
I do wish C++ applied public inheritance by default though since that's generally a much more common case. Then again, we could just all use structs instead. :-D
The third party library's class contains a protected member. How can I access it if we cannot modify the code of the third party library?
A protected member can only be accessed by the class itself, subclasses, or friend classes and methods. The only way to access the protected member is to subclass the class, then use your subclass to expose the protected member.
Eg:
class parent {
/* Other members */
protected:
int foo();
}
class child : public parent {
public:
int foo();
}
You should make a special wrapper for that class. Just inherit library's class and gain the access to protected members. Due to inheritance, it is possible to use the wrapper class instead of the base class in your following code.
You can access protected members from a derived class.
class A
{
protected:
int i;
};
class B : public A
{
void func()
{
i; //valid
}
};
If I have two classes for example as follows:
class A {...}
class B {...}
If I want to make class A public to class B, do I just make the members of class A public or I can just use public class A {...}?
Is there a way to tell class B for example that only class A is public for you? In other words, can I make public classes to A protected or private to others? Or, this is just a matter of deriving a class (inheritance)?
Thanks.
There's a substantial difference between making the class public and making its contents public.
If you define your class in an include file (.h file) then you are making your class public. Every other source file that includes this include file will know about this class, and can e.g. have a pointer to it.
The only way to make a class private, it to put its definition in a source (.cpp) file.
Even when you make a class public, you don't necessarily have to make the contents of your class public. The following example is an extreme one:
class MyClass
{
private:
MyClass();
~MyClass();
void setValue(int i);
int getValue() const;
};
If this definition is put in an include file, every other source can refer to (have a pointer to) this class, but since all the methods in the class are private, no other source may construct it, destruct it, set its value or get its value.
You make the contents of a class public by putting methods from it in the 'public' part of the class definition, like this:
class MyClass
{
public:
MyClass();
~MyClass();
int getValue() const;
private:
void setValue(int i);
};
Now everybody may construct and destruct instances of this class, and may even get the value. Setting the value however, is not public, so nobody is able to set the value (except the class itself).
If you want to make the class public to only some other class of your application, but not to the complete application, you should declare that other class a friend, e.g.:
class SomeOtherClass;
class MyClass
{
friend SomeOtherClass;
public:
MyClass();
~MyClass();
int getValue() const;
private:
void setValue(int i);
};
Now, SomeOtherClass may access all the private methods from MyClass, so it may call setValue to set the value of MyClass. All the other classes are still limited to the public methods.
Unfortunately, there is no way in C++ to make only a part of your class public to a limited set of other classes. So, if you make another class a friend, it is able to access all private methods. Therefore, limit the number of friends.
You can use friendship.
class A { friend class B; private: int x; };
class B { B() { A a; a.x = 0; // legal };
If B has a strong interdependence to A, i suggest you use a nested class. Fortunately, nested class can be protected or private.
class A {
protected:
// the class A::B is visible from A and its
// inherited classes, but not to others, just
// like a protected member.
class B {
public:
int yay_another_public_member();
};
public:
int yay_a_public_member();
};