How can I access to a "parent" protected member? - c++

This is a "simulation" of my code:
#include <string>
#include <iostream>
using namespace std;
class A
{
protected:
int test = 10;
};
class C;
class B : public A
{
private:
C *c;
public:
B();
};
class C
{
public:
C(B *b) {
cout << b->test;
}
};
B::B() {
c = new C(this);
}
int main()
{
B();
}
I can't touch the protected status type of that test variable, since is from another Framework and I don't have real "access".
I need to create an instance of class C from B (which extend A), passing B to it and access (from C) to the param test of A.
Is there a fancy way for doing it? Within B I can use test without any problem...

The C class doesn't inherit from B, so B is not a parent, so the C class has no access to the protected members.
Workaround
If you control B and C but are not allowed to touch A which comes from another framework, you could try:
class B : public A
{
private:
C *c;
public:
B();
friend C; // Make C a friend of B so that it has access.
};
Online demo
Advise
Despite there is a technical workaround to achieve what you want, it might not be advisable to do so. The idea of protected members is that it's implementation details only relevant to derived classes. By opening it with a friendship, you create a dependency to implementation details you are not supposed to have access to. So you'd violate the framework's design principle. Possible but at your own risk.
Another approach could be to add a public getter to the protected element in B and then in C refer to this public member (demo). It's better but you'd still expose data that you're not supposed to.

You can also add a public accessor in B:
class B : public A
{
private:
C *c;
public:
B();
int get_test() const { return this->test; }
};

Related

Complex object inside another one

I have the following class
class A {
private:
B b;
public:
A();
}
class B {
public:
void foo();
void bar();
void foz();
........
}
B has a lot of methods. Sometimes is needed for a "customer" of class A to use method of class B. I could return a reference of B, but in this case I should return a const reference because returning a non-const reference of a private object is not good programming. If the reference is const, foo, bar and so on can't be called because they aren't const. So the only "clean" way seems to recreate the same interfaces in A using delegation to B. But this approach is not really good because I should recreate all the interfaces in A. As alternative I could set B as public in A, but it seems "strange" to me. What should I do in this case?
That is mainly an encapsulation question, and what you want to advertise in the public interface of class A.
If class B is also a public class - read can normally be used by users of class A and not a class internal to a library or framework - and if you want the existence of a B subobject to exist in the public documentation of class A and if you want to allow any operation on the B object, you can safely provide a getter.
If any of the above conditions is false, then the getter would break encapsulation and you would better define delegating methods in class A.
Depending on the general design, it could make sense to declare an interface class (say C) with only the methods that you want to allow from class A, and have B a subclass from C. Then you could safely declare a getter returning a reference on a C object:
class C {
public:
void foo(); // optionally virtual or pure virtual...
void bar();
void foz();
};
class B: public C {
.... // other members not relevant for what is public for A users
};
class A {
private:
B b;
public:
A();
C& getB() {
return b;
}
};
Solution 1. You create a getb() and return reference to B. Its not bad programming in you case particularly.
Solution 2. Create interface function for each corresponding function of b and call them.
void A::foo()
{
b.foo();
}
You can make the data member protectedinstead of private. Documentation says that protected members are not as private as private members, which are accessible only to members of the class in which they are declared, but they are not as public as public members, which are accessible in any function. protectedmembers (be they data members of method members) serve the role you're looking for : they are not accessible from everywhere (safe coding practices), but you can still manage them in clean ways when it makes sense :
If class A has an attribute of type B, is has access to B's
protected and publicmembers
friendfunctions can access both protected and publicmembers of a class they are friend with.
When preceding the name of a base class, the protected keyword specifies that the public and protected members of the base class are protected members of its derived classes.
Here, you're interested by the first item of the list : you can access B' methods from A; BUT B has still safeguards.
When I run the following code (adapted from your code) :
#include <iostream>
using std::cout;
using std::endl;
class B {
public:
void foo() { cout << "foo" << endl; };
void bar() { cout << "bar" << endl; };
void foz() { cout << "foz" << endl; };
};
class A {
protected: // <===== THIS IS THE SIGNIFICANT BIT
B b;
public:
A() {
b.foo();
b.bar();
b.foz();
cout << "A constructor" << endl;
};
};
int main(int argc, char** argv) {
A myA;
return 0;
}
I get the following console output :
foo
bar
foz
A constructor
Which shows that I can access B's methods from A.

Using a Variable of an Instance within the Method of another Class in C++

I was wondering how I would go about using a variable of a specific instance of a class within a function of another class.
To provide an example of what I'm trying to do, say I've 3 classes a,b and c. Class c inherits from class b, and a single instance of b and c are called within a method in class a and b respectively. How would I go about using the variable of int pos (see below) within a specific instance of class a in class c?
class a
{
private:
void B(); //Calls an instance of class c
int pos; //Variable that I want to use in c
};
class b : public c
{
private:
void C(); //Calls an instance of class b
};
class c
{
private:
void calculate(int _pos); //Method which requires the value of pos from class a
};
Help would be greatly appreciated, thank you!
Your code sample doesn't make much sense for me, and you aren't really clear what you want to achieve.
"How would I go about using the variable of int pos (see below) within a specific instance of class a in class c?"
Fact is you can't access any private class member variables from other classes.
Since class c and class b aren't declared as friend for class a, these cannot access the pos member from a::pos directly. You have to pass them a reference to class a; at some point, and provide public (read access) to pos with a getter function :
class a {
int pos; //Variable that I want to use in c
public:
int getPos() const { return pos; } // <<< let other classes read this
// property
};
And use it from an instance of class c() like e.g. (constructor):
c::c(const a& a_) { // <<< pass a reference to a
calculate(a_.getPos());
}
I'm not sure if I understand your problem, but if you want to access a member of a class instance from a non-friend non-base class, that member must be exposed of there must be some function that access it. For example:
class a
{
public:
int getPos() const { return pos; }
private:
void B(); //Calls an instance of class c
int pos; //Variable that I want to use in c
};

OOPS Memory Allocation for Base class under Inheritance?

Program:
class A
{
int a;
public:
void geta()
{
a=10;
}
void puta()
{
cout<<"a : "<<a;
}
};
class B : public A
{
int b;
public:
void getb()
{
geta(); b=20;
}
void putb()
{
puta(); cout<<"b : "<<b;
}
};
int main()
{
B ABC;
ABC.getb();
ABC.putb();
return 0;
}
The Problem:
The above program allocates memory for derived class object & calls its relevant methods.
The base class is inherited as public, and as the variable 'a' is a private member, it will not get inherited.
So, the program should not allocate memory for this variable.
But, when the above is executed, 'a' variable will be allocated even though it is not inherited.
Could anyone help me understand this?
Thank You.
as the variable 'a' is a private member, it will not get inherited. So, the program should not allocate memory for this variable.
Your assumption is mistaken. Public inheritance models an "is-a" relationship. That is, class Derived is-a Base. Anything you can do with a Base, you should be able to do with a Derived. In order for this to be true, it necessarily must contain everything that Base contains.
In your example, it's perfectly legal to say:
B b;
b.put_a();
that is, to use A methods on B object. This would not work if the a member was absent.
The base class is inherited as public, and as the variable 'a' is a private member, it will not get inherited.
When a base class member is declared as private it doesn't mean it does not get inherited. It just means that the member variable will be inherited (will be part of the derived class) but won't be accessible.
For example, in:
class A {
private:
int a;
int b;
// ...
};
class B : public A {};
auto main() -> int {
B b;
}
When we allocate B b; we are allocating both a and b member objects of the class A.
The variable a is inherited, though you have no access to it. For example, the following code would work:
class A {
private:
int x;
public:
int getXfromA() { return x; }
};
class B : public A {
public:
int getXfromB() { return getXfromA(); }
};
However, x cannot be directly accessed from B class here.
You're confusing storage with access control.
If object B inherits from object A, it has all of object A's methods and members, even if it cannot access them directly.
The purpose of private and protected is access control. If you mark members and methods as private, then nothing outside can access those methods and members. But, those things are part of the object nonetheless.
This allows you to implement class invariants without exposing the details, including classes that inherit from the base.
Here's an example that encapsulates capturing the creation time of an object in the base class:
#include <time.h>
#include <iostream>
class Base
{
private:
time_t create_time;
public:
Base()
{
create_time = time(0);
}
time_t get_create_time() { return create_time; }
};
class Derived : public Base
{
public:
Derived() { }
};
int main()
{
Derived D;
std::cout << D.get_create_time() << std::endl;
}
Derived doesn't know or need to know how the creation time was captured. It's a class invariant it inherited by deriving from Base.
This is a pretty simple example, but you could imagine more complex examples.

Making the parent private and the grandparent public for a class

Short story:
is it possible to do
class A{};
class B:public virtual A{};
class C:public virtual A,private B{};
i.e. "showing" that C is an A and not a B, but making it actually a B
without adding the virtual (and the corresponding vptrs)?
Long story:
A has several methods.
B adds some more.
Sometimes I want to forbid the use of one of them. C has this purpose.
The program has many B, few Cs. I do not want then to make B a subclass of C.
Yes, this will do exactly what you intend it to do.
But consider another option: inheriting publicly and hiding the unwanted methods:
class A
{
public:
int a() {return 0xaa;}
};
class B: public A
{
public:
int b() {return 0xbb;}
};
class C: public B
{
private:
using B::b; // makes the method called b private
};
...
B().b(); // OK, using method b in class B
C().b(); // error: b is private in class C
C().B::b(); // OK: calling b in base-class (not sure if you want to prevent this)
This will work with both virtual and non-virtual inheritance.

C++ Encapsulation Techniques

I'm trying to properly encapsulate a class A, which should only be operated on by class B.
However, I want to inherit from class B.
Having A friend B doesn't work -- friendship isn't inherited.
What's the generally accepted way of accomplish what I want, or am I making a mistake?
To give you a bit more color, class A represents a complex system's state. It should only be modified by B, which are actions that can be applied to change class A's state.
It sounds like you may need to do a redesign; your class A represents a State, but your Class B represents a set of actions. There's a relationship there, but it's not an inheritance relationship. I'd suggest composition; you want more of a HASA relationship than an ISA relationship, as far as I can tell.
I assume you want to allow descendants of B to access A directly? If A and B are tightly coupled, you can make A a protected class definition within B itself, instead of being an independent definition. E.G.
class B
{
protected:
class A
{
};
};
Another idea is to create protected methods on B that delegate their actions to A. E.G.
class A
{
friend class B;
private:
void DoSomething();
};
class B
{
protected:
void DoSomething(A& a) { a.DoSomething(); }
};
If I understand you correctly, you want to have B and it's derivatives to have access to the internal implementation of class A, yes?
Unfortunately, C++ does not have the concept of "internal" protection levels that languages like C# and Java posses.
You can consider using the private implementation paradigm (pimpl) - also known as opaque pointers, to expose functionality within your system using public access levels, that consumers of A and B would not see.
Keeping everything as is, the easiest thing to do is to add protected methods to B that give access to the equivalent feature of A it would need. This opens the encapsulation to just subclasses of B.
The most straightforward way to do this is simply to have B contain an A:
class B {
protected:
A a_;
};
Then, you can write a class C which inherits from B and is able to manipulate A. If C shouldn't be able to do arbitrary things to the A, then make the A private in B and provide protected methods in B that C can use to do approved things to the A, like so:
class B {
private:
A a_;
protected:
void doSomethingToA();
};
Containment is the way to go (class B contains private member of type A) unless B needs to override some virtuals in A, in which case private inheritance is the closest thing.
I cant see why you would want to inherit. Make everything in A private and friend B. B then has a member of A which it can freely manipulate.
The way you describe this it sounds more like composition rather than inheritance. E.g.
class ComplexMachine {
public:
setState(int state);
};
class Operator {
public:
Operator(ComplexMachine & m) :_m(m) {};
void drive() { _m->setState(1); }
void turn() { _m->setState(2); }
void stop() { _m->setState(0); }
private:
ComplexMachine _m;
};
class SmoothOperator : public Operator { }
Working with the bits of information you have given:
Class B should be responsible for preserving the invariants of class A, and class B should be the only way to manipulate A. Any client - derived class or caller - should not need to know that A exists.
(From design POV, there's even no need for A to exist, but I have encountered enough practical reasons for such a separation that I won't hold it against you ;))
This might require a lot of boilerplate code to be written, or some trickery with the interface. e.g. if client should be allowed to use class A to query information but not to modify it, B could hand out a const & to the aggregated A. With a compiler supporting __declspec(property) or similar, the syntactic pain can be eased.
If you want to be sure that only B operates on A, make the instance of A private and expose a protected interface from B to its descendants.
class A
{
public:
void foo() {}
};
class B
{
private:
A a;
protected:
void CallAFoo() { a.foo() };
};
class C : public B
{
void goo() { CallAFoo(); }
};
From what I understand from your question, you will need some polymorphism. You need an abstract class A and class B inherits class A. Also, the protected keyword allows the classes that inherit to have access to certain information while at the same time deny access to anything else. Here is a little example:
// dynamic allocation and polymorphism
#include <iostream>
using namespace std;
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void) =0;
void printarea (void)
{ cout << this->area() << endl; }
};
class CRectangle: public CPolygon {
public:
int area (void)
{ return (width * height); }
};
class CTriangle: public CPolygon {
public:
int area (void)
{ return (width * height / 2); }
};
int main () {
CPolygon * ppoly1 = new CRectangle;
CPolygon * ppoly2 = new CTriangle;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly1->printarea();
ppoly2->printarea();
delete ppoly1;
delete ppoly2;
return 0;
}
Code taken from cplusplus.com (contains information on polymorphism and abstract classes too).