C++ Encapsulation Techniques - c++

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).

Related

How can I access to a "parent" protected member?

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; }
};

Alternative for forward declaration: two classes using each other

I have class A which has to implement some functions. Since implementing one of them needs it's own data structures, I assumed A contain another class B, which has all needed data structures and functions. However, B is also need to use data structures and functions of A, as well. I used two classes calling each others using forward declaration. But there is still problems. For example, I need to make all data structures in A public, in order to B can access it. I tried using friend classes, but when I declare B as an abstract classes with sub-classes which implements B's functionalities, I need to make all data structures of A, as public. Because friend class doesn't work for inherited sub-classes, all data structures of A, needs to be public. This makes my design quite messy.
class B;
class A{
protected:
int ds[100];
B * b;
public:
a_func(){
b->b_func();
}
};
class A;
class B{
A * a;
public:
b_func(){
a->a_func();
}
};
class sub_B:public B{
public:
b_func(){
a->a_func();
a->ds ...;
}
}
My question is: is there any alternative design?
I also tried making A an abstract class and class B implements a function of it, however, it doesn't conceptually makes sense to build an object of B, when I want an object of A.
You don't have to provide member function definitions inside a class definition:
class A;
class B;
class A {
// no need for public
B * b;
void a_funct(void);
};
class B {
// no need for public here, too
A * a;
void b_funct(void);
};
// the following goes in a source file,
// otherwise you should mark it as inline
void A::a_funct() {
b->b_funct();
}
void B::b_funct() {
a->a_funct();
}
Note that above code serves only as example, in its current shape it's nothing but a fancy endless (recursion) loop.

Cast member of virtual base class

I know that this code won't work and I also know why, but is there an alternative?
class A
{
public:
A(void){}
virtual ~A(void){}
protected:
A* parent;
int a;
};
class B : public virtual A
{
public:
B(void){}
virtual ~B(void){}
protected:
void f(){ ((B*)parent)->a; }
};
It is not possible to cast parent to a B*, since A is a virtual base class. Not casting parent also gives an error. I hope I don't have to make all members public. Does someone have an idea how to access A::a?
Edit
Using friends doesn't work, since classes derived from B don't have access to A::a.
Some options:
Make a public
Create a public setter/getter method for a -
make B a friend of class A (or just the function f())
The 3rd option his works better than the other 2 if you want to allow only A (or a specific function) to have access to members of A. On the other hand with the other 2 options you can make only that member public (but it will be public to everyone)
Making an answer from my comment above because I tested it and it compiles fine.
Without the cast, it probably fails because you are trying to access a protected field of A in B. You can just add a public getter and remove the cast to B*
class A
{
public:
A(void){}
virtual ~A(void){}
int getA() { return a; }
protected:
A* parent;
int a;
};
class B : public virtual A
{
public:
B(void){}
virtual ~B(void){}
protected:
void f(){ (parent)->getA(); }
};
This works:
class A {
public:
A(void){}
virtual ~A(void){}
protected:
A* parent;
int a;
int parent_a(){ return parent->a;}
};
class B : public virtual A
{
public:
B(void){}
virtual ~B(void){}
protected:
void f(){ A::parent_a(); }
};
Note that:
a doesn't get exposed to the outside world,
the retrieved a is necessary the correct one, since B inherit virtually from A, so a successful dynamic cast of parent to B before getting its a field should return the same one as the solution offered above.
Now, why does this work?
Because a class is implicitely friend of itself.
That's what dynamic_cast is for. If you don't want to redesign your code, just replace the C-style cast with a dynamic_cast:
void f() { dynamic_cast<B*>(parent)->a; }
For this to work correctly, A must have at least one virtual function (as this one does). In addition, the cast will produce a null pointer if parent does not, in fact, point to an object of type B.
class B : public virtual A
{
public:
B(void){}
virtual ~B(void){}
protected:
void f(){ this->a; }
};
you're allowed to access protected member from parent class (A mother class of B).
I think the problem here is not so much how to access the element a, but why you need a tree of diamond hierarchies in your design. You should at first step back and evaluate if you really need a tree of diamonds.
If you do, then instead of your current approach, provide A with a nice appropriate (public) abstract interface that can be called from B. When you start accessing parent protected attributes directly you tightly couple components, making it easy to break your code and making it very hard to change your design later in the application's lifespan.
Thanks everyone, some usable possibilities were mentioned, like using friends and creating additional functions for each variable. This could work in some scenarios, but not in my case. Adding each derived class as a friend has the problem that it makes the library less user friendly when they want to add a class. Adding functions per variable would add over hundred extra functions for some classes.
What I did as my final solution was creating a copy instead of a cast. Though it will run a little bit slower, the code will remain clean. To counter the speed problem. Accessing local variables is a lot faster than accessing global variables.
This is how it looks now:
class A
{
public:
A* parent;
virtual ~A(void){}
virtual A & operator = (const A & x)
{
a = x.a;
parent = x.parent;
return *this;
}
protected:
int a;
};
class B : public virtual A
{
public:
B(void){}
virtual ~B(void){}
using A::operator =;
virtual B & operator = (const B & x)
{
A::operator = (x);
return *this;
}
void f(void)
{
B p;
p = *parent;
int x = p.a;//Allowed.
}
};
If you have a better solution, please feel free post it.

Multiple Inheritance from same grandparent - merge implementations?

for a certain project I have declared an interface (a class with only pure virtual functions) and want to offer users some implementations of this interface.
I want users to have great flexibility, so I offer partial implementations of this interface. In every implementation there is some functionality included, other functions are not overridden since they take care about different parts.
However, I also want to present users with a fully usable implementation of the interface as well. So my first approach was to simply derive a class from both partial implementations. This did not work and exited with the error that some functions are still pure virtual in the derived class.
So my question is if there is any way to simply merge two partial implementations of the same interface. I found a workaround by explicitely stating which function I want to be called for each method, but I consider this pretty ugly and would be grateful for an mechanism taking care of this for me.
#include <iostream>
class A{
public:
virtual void foo() = 0;
virtual void bar() = 0;
};
class B: public A{
public:
void foo(){ std::cout << "Foo from B" << std::endl; }
};
class C: public A{
public:
void bar(){ std::cout << "Bar from C" << std::endl; }
};
// Does not work
class D: public B, public C {};
// Does work, but is ugly
class D: public B, public C {
public:
void foo(){ B::foo(); }
void bar(){ C::bar(); }
};
int main(int argc, char** argv){
D d;
d.foo();
d.bar();
}
Regards,
Alexander
The actual problem is about managing several visitors for a tree, letting each of them traverse the tree, make a decision for each of the nodes and then aggregate each visitor's decision and accumulate it into a definite decision.
A separation of both parts is sadly not possible without (I think) massive overhead, since I want to provide one implementation taking care of managing the visitors and one taking care of how to store the final decision.
Have you considered avoiding the diamond inheritance completely, providing several abstract classes each with optional implementations, allowing the user to mix and match default implementation and interface as needed?
In your case what's happening is that once you inherit to D, B::bar hasn't been implemented and C::foo hasn't been implemented. The intermediate classes B and C aren't able to see each others' implementations.
If you need the full interface in the grandparent, have you considered providing the implementation in a different way, possibly a policy with templates, and default classes that will be dispatched into to provide the default behavior?
If your top level interface has a logical division in functionality, you should split it into two separate interfaces. For example if you have both serialization and drawing functions in interface A, you should separate these into two interfaces, ISerialization and IDrawing.
You're free to then provide a default implementation of each of these interfaces. The user of your classes can inherit either your interface or your default implementation as needed.
There is also the possibility that you could use a "factory" class for the main interface type. In other words the primary interface class also contains some type of static function that generates an appropriate child class on-request from the user. For instance:
#include <cstdio>
class A
{
public:
enum class_t { CLASS_B, CLASS_C };
static A* make_a_class(class_t type);
virtual void foo() = 0;
virtual void bar() = 0;
};
class B: public A
{
private:
virtual void foo() { /* does nothing */ }
public:
virtual void bar() { printf("Called B::bar()\n"); }
};
class C: public A
{
private:
virtual void bar() { /* does nothing */ }
public:
virtual void foo() { printf("Called C::foo()\n"); }
};
A* A::make_a_class(class_t type)
{
switch(type)
{
case CLASS_B: return new B();
case CLASS_C: return new C();
default: return NULL;
}
}
int main()
{
B* Class_B_Obj = static_cast<B*>(A::make_a_class(A::CLASS_B));
C* Class_C_Obj = static_cast<C*>(A::make_a_class(A::CLASS_C));
//Class_B_Obj->foo(); //can't access since it's private
Class_B_Obj->bar();
Class_C_Obj->foo();
//Class_C_Obj->bar(); //can't access since it's private
return 0;
}
If class A for some reason needs to access some private members of class B or class C, just make class A a friend of the children classes (for instance, you could make the constructors of class B and class C private constructors so that only the static function in class A can generate them, and the user can't make one on their own without calling the static factory function in class A).
Hope this helps,
Jason
Since you mentioned that you mainly needed access to the functions rather than data-members, here is another method you could use rather than multiple inheritance using templates and template partial specialization:
#include <iostream>
using namespace std;
enum class_t { CLASS_A, CLASS_B, CLASS_C };
template<class_t class_type>
class base_type
{
public:
static void foo() {}
static void bar() {}
};
template<>
void base_type<CLASS_A>::foo() { cout << "Calling CLASS_A type foo()" << endl; }
template<>
void base_type<CLASS_B>::bar() { cout << "Calling CLASS_B type bar()" << endl; }
template<>
void base_type<CLASS_C>::foo() { base_type<CLASS_A>::foo(); }
template<>
void base_type<CLASS_C>::bar() { base_type<CLASS_B>::bar(); }
int main()
{
base_type<CLASS_A> Class_A;
Class_A.foo();
base_type<CLASS_B> Class_B;
Class_B.bar();
base_type<CLASS_C> Class_C;
Class_C.foo();
Class_C.bar();
return 0;
}
Now if you need non-static functions that have access to private data-members, this can get a bit trickier, but it should still be doable. It would though most likely require the need for a separate traits class you can use to access the proper types without running into "incomplete types" compiler errors.
Thanks,
Jason
I think the problem is that when using simple inheritance between B and A, and between C and A, you end up with two objects of type A in D (each of which will have a pure virtual function, causing a compile error because D is thus abstract and you try to create an instance of it).
Using virtual inheritance solves the problem since it ensure there is only one copy of A in D.

Inheritance without containing?

I have class A. And I have class B. And I have many-many classes derived from class B.
I want to achieve this: derivatives of B should have access to the protected variables of A. Whithout each of them containing an instance of A, which would need a lot of memory.
So I guess public inheritance is not a good idea this time. How do I solve this?
Thanks!
You could do it with friend and accessor functions. This does trust B to stay off A's privates - don't see a good way to let only B and subclasses access only protected members of A unless there's an inheritance relationship between A and B.
class A {
friend class B;
protected:
int X;
};
class B {
protected:
static int getX(A const & a) { return a.X; }
};
class C : public B {
public:
void foo(A const & a) { int bar = getX(a); }
};
Make the classes that are derived from B friends of A.
From what I understand children of B are unrelated to class A and as such should not have access to non-public parts of A.
The right way to get access to A's data within B child classes is through A's public interface. If such public interface isn't adequate then that's a signal that either you're trying to do something that's a poor design, or that A's public interface needs to be improved.