C++ Class in class method inheritance - c++

I have the following structure, and I would like to call foo from D. How is it possible? I got the error message, that I commented at the line below.
class A
{
protected:
class B
{
public:
B(x)
{
//...
}
protected:
virtual void foo()
{
//...
}
};
};
class C : public A
{
protected:
class D : public A::B
{
public:
D(x) : B(x)
{
//empty
}
};
void bar()
{
D var = D(x);
var.foo(); //cant access protected member in class A::B
}
};

foo() is protected member function of B, means that foo() is only allowed to be called from its subclass( child class).
bar() is member function of C, and C is inheritance from A. So ,C is not subclass of B.
If you put bar in D, that's OK.As code below:
class A
{
protected:
class B
{
public:
B(int x)
{
//...
}
protected:
virtual void foo()
{
//...
}
};
};
class C : public A
{
protected:
class D : public A::B
{
public:
D(int x) : B(x)
{
//empty
}
// Here is OK, while D is subclass of B
void bar()
{
int x;
D var = D(x);
var.foo(); //cant access protected member in class A::B
}
};
// void bar()
// {
// int x;
// D var = D(x);
// var.foo(); //cant access protected member in class A::B
// }
};
int main(){
return 0;
}

Try a friend class. You can make D a friend of B, and that should allow D to call foo().

Actually you are trying to access from the class C a protected method of the class D ==> You can't access protected methods from the external of a class.
One solution could be to declare C as a friend class of D so C can access protected methods:
// ...
class D : public A::B
{
public:
D(x) : B(x)
{
//empty
}
// Declare C as friend of D
friend class C;
};
// ...
Adding the friendship declaration your code will compile and will work as expected.

You might want foo() to be public in D even though it is protected in A::B
If so you can add the following line after the public: line in the definition of D
using A::B::foo;

Thanks for the answer. Making the foo function public is really a solution, but I really want foo only available from inherited class. The friend modifier is a thing, what many people hate, because it gives you access for things, thats you should not access.
But also you were right guys, I should access B::foo from D (from constructor is not an option is my case). I could create a function, which calls the original foo, so my solution is:
class A
{
protected:
class B
{
public:
B(x)
{
//...
}
protected:
virtual void foo()
{
//...
}
};
};
class C : public A
{
protected:
class D : public A::B
{
public:
D(x) : B(x)
{
//empty
}
Dfoo()
{
B::foo();
}
};
void bar()
{
D var = D(x);
var.Dfoo();
}
};
The solution was easy, but I did not know that a function (what is not static) can be called like this :)

Related

Access inner class private variable in outer class

//In file1.hpp
class A
{
protected:
class B
{
public:
B () {};
};
};
// In file2.hpp
class C
{
public:
void getValue()
{
D obj; ---- error: no matching function for call to D
printf("%d\n",obj.c);
}
class D : public A::B
{
friend class C; -- I tried writing this but still no luck.
public:
D(int a, int b) : c(a), d(b) {}
virtual ~D() {}
//something
private:
int c; int d;
};
class E : public D
{
E() : D(1,2) {}
virtual ~E() {}
};
}
int main()
{
C::E obj;
}
In the public function, getValue I want to access the private member variables of the class D which are (c and d). How can I do that? I tried putting "friend class C" inside class D and then tried creating an object of class D inside getValue function but instead of getting a value like c=5 or d=6, I always get 0.
If I print the value in the following area, I get the correct value. I won't be able to show you how getValue is called but just imagine that it is called somehow. I just need to print c,d in that.
D(int a, int b)
: c(a), d(b) {};
EDIT: At the time of instantiation in getValue, I do something like this
D obj; --- error: no matching function for call to D
Let take the following example:
#include <iostream>
//In file1.hpp
class A
{
protected:
class B
{
public:
B () = default;
};
friend class C; // <-- bad idea
};
// In file2.hpp
class C
{
public:
void getValue()
{
// Creating an object E?
E objE;
// Access c and d
std::cout << "c:" << objE.c << ", d:" << objE.d << std::endl;
}
class D : public A::B // <-- bad idea?
{
public:
D(int a, int b): c(a), d(b) {}
virtual ~D() {}
//something
private:
int c; // dangerous to not initialize basic types
int d;
friend class C; // <-- bad idea
};
class E : public D
{
public:
E() : D(1,2) {}
virtual ~E() {}
};
};
int main()
{
C objC;
objC.getValue();
}
( you can run it here: https://onlinegdb.com/hNfm7Pvg0f )
First is, to have an instance of E to access in C::getValue, so I instantiated an object.
private and protected indicate that those properties and methods are not available publicly (encapsulation) and that is exactly what you are trying to do. You can make exceptions with friend keyword, but that is rarely a good idea (I probably use it twice in my 20 years carrier). But hey! it works.

c++ Getting access to member outside from inheritance chain

I have the following design:
- one class A that has a protected member of class M.
- one class B that inherits from A and has a pointer to an object of class C
- one class C that needs to have access to the member of the class A
class A {
public:
A() : _member(0) {}
~A() { delete _member }
protected:
M _member;
}
class B : public A {
public:
B(){}
~B(){}
protected:
C* c;
}
class C {
// C needs to have access to _member
}
What design should be more appropriate to solve this issue ?
In pure OO terms, allowing a class to directly access the internal fields of another class is bad practice.
That said, C++ is not a pure OO language, and does allow for this (among other important deviations from OO).
To allow access to a private member to another class, you must designate that class to be a friend. Friendship, however is not passed to derived classes, therefore you must upcast the class to the type you need.
This is your simplest solution:
class A {
public:
A() : _member(0) {}
~A() { delete _member }
protected:
friend class C;
M _member;
}
class B : public A {
public:
B(){ c = new C(this); } // this call will cast the B* to an A* (important)
~B(){ delete c;}
protected:
C* c;
}
class C {
public:
C(A* a) { _a->_member = new M(); } //Now C can directly access _member in A
}
In such a way, any object derived from A can be turned back into an A* and used to access _member.
However, as previously stated, any classes derived from C will not gain access to _member, as friendship is not inherited, so a more comprehensive solution is required:
class M {
public:
void Foo() { printf("Foo called\n"); }
};
class A {
M* m;
friend class C;
public:
A():m(0) { ; }
};
class B :public A {
int id;
public:
B() { id = 0; }
};
class C {
public:
C() { _a = 0; }
C(A* a) { _a = a; }
protected:
M* getM() { return _a->m; }
void setM(M* m_) { _a->m = m_; }
private:
A* _a;
};
class D : public C {
public:
D(B* b): C(b) {
}
void Foo() {
setM(new M());
getM()->Foo();
delete getM();
setM(nullptr);
}
};
int main()
{
B* b = new B();
D d(b);
d.Foo();
delete b;
getchar();
return 0;
}
In this way, no classes derived from A provide direct access to _member, and no classes derived from C have direct access, but the member variable can still be accessed via C's protected API. This also prevents other external objects accessing it.
Make C a friend of A:
class A {
friend class C;
/*and so on*/
Then C can see all member variables and functions in A, even if they are private.

c++: How do you access base class calls in multiple/multilevel inheritance from within the class?

This is the simplified code:
class a
{
public:
void func( void )
{
//Want to call this
}
int avar;
};
class b : public a
{
public:
void func( void )
{
}
};
class c : public a
{
public:
void func( void )
{
}
};
class d : public b, public c
{
public:
void d1()
{
//b::a::avar;
//c::a::avar;
//b::a::func();
//c::a::func();
}
};
How do you properly qualify a call to access the members of both instances of the subclass a, the things I've tried leads to a 'a is an ambiguous base of d' error. Same question if the hierarchy was one more class deep or if a class template was involved. I'm not looking for a virtual base.
You can call the immediate base class functions using the explicit calls.
void d1()
{
b::func();
c::func();
}
You can call a::func from b::func similarly.
class b : public a
{
public:
void func( void )
{
a::func();
}
};
If you also want to access the member a::var and call a::func directly from d::d1, you can use:
void d1()
{
b* bPtr = this;
bPtr->avar; // Access the avar from the b side of the inheritance.
bPtr->a::func(); // Call a::func() from the b side of the inheritance
c* cPtr = this;
cPtr->avar; // Access the avar from the c side of the inheritance.
cPtr->a::func(); // Call a::func() from the c side of the inheritance
}

Allow class access to single private member

I have a class A which has a private method called a(). I have also a class B which needs to access a() (but just B should have access to a(), thats why a() is private). I could now use a friend specifier but that would make other private methods of A (lets call them b() and c()) also available to B and I dont want that behaviour.
Is there a way to make just a() of A accessable to B?
There is a way -- if your class has a public template function:
class A {
// apparently private
void priv () { std::cout << "got you A::a()" << std::endl ; }
public:
template <class T>
void abuse() {}
};
struct Thief {};
template <>
void A::abuse<Thief>() {
this->priv();
}
int main() {
A a;
// obviously do not compile : a.priv();
// this i OK
a.abuse<Thief>();
return 0;
}
I must confess I stole this from GotW...
No there's not, but as you specify the precise class, just B could access A's private members.
You just have to take care of what method are called.
As friend relationship are not inherited, you don't have to worry about B's possible subclasses.
This could be done with some "twist".
Just factor out method a() from A class into a parent class that has B as a friend class, then let A inherit it. this will leave a() as being a method in A, but the only private method accessible by its parent's friend B.
here is a very simple code to clarify what I've said:
class parent
{
friend class B;
private:
void a() {}
};
class A:public parent
{
private:
void b() {}
void c() {}
};
class B
{
A* m_a;
public :
B()
{
m_a = new A();
m_a->a(); // OK
m_a->b(); // error C2248: 'A::b' : cannot access private member declared in class 'A'
}
};
hope it helps !
Yes, I have an easy way. Let B have a pointer of A::a(), like this:
typedef boost::function<void ()> functype;
class A {
private:
void a();
};
class B {
public:
void setfp(functype f) {m_f = f;}
void foo() {
// do some stuff
m_f();
}
private:
functype m_f;
};
A a;
B b;
b.setfp(boost::bind(&A::a, &a));
b.foo();

Initializing an abstract class?

Here is my issue. I want to have something like this:
class A {
protected:
int someInt;
virtual void someFunc() = 0;
};
class B : public A {
protected:
virtual void someFunc() { // uses someInt}
public:
B() {//tell the A inside of B to set someInt to whatever it wants}
};
so basically, someInt can be changed, it's not constant, but I want all the classes that implement A to use a value provided by A for someInt.
Thanks
You can use initializer lists in the constructor to call parent constructors:
class A {
protected:
int someInt;
virtual void someFunc() = 0;
A(int x) : someInt(x) {} // Base-class constructor (initialises someInt)
};
class B : public A {
protected:
virtual void someFunc() {}
public:
B() : A(10) {} // Initialises base class via constructor
};
Is this what you want?
class A
{
protected:
int someInt;
public:
A(int _val) : someInt(_val)
{
}; // eo ctor
}; // eo class A
class B : public A
{
public:
B() : A(5) // initialise someInt with 5
{
}; // eo ctor
}; // eo class B
Note, that as "someInt" is protected, you can just set it in B's constructor anyway.
B()
{
A::someInt = 5;
}; // eo ctor
I am not sure what you want, but if you initialize someInt in the constructor of A, subclasses will see that value.
class A {
public:
A() : someInt(5) {}
protected:
int someInt;
virtual void someFunc() = 0;
};
class B : public A {
protected:
virtual void someFunc() { // uses someInt}
public:
B() {// at this point someInt will already have been initialized to 5}
};
When the subclass is constructed, the baseclass constructors are executed first.
class A {
protected:
int someInt;
virtual void someFunc() = 0;
A(){//set someInt here}
};
class B : public A {
protected:
virtual void someFunc() { // uses someInt}
public:
B():A() {}
};
A protected constructor will achieve this. As above. The solutions using a public constructor are fine too, but as the constructor cannot be called directly on thr interface I think protected is better.