Helper struct to expose data member to public - c++

so I am trying to construct a class with helper method, namely:
class Type{
int a, b, c;
friend auto helper(auto);
friend auto test_helper(auto);
/* couples test with implement */
public:
void method(){
helper(this);
}
};
But making helper a friend function couples the test with implementation if we want to test helper.
So I want to make helper a free function, namely:
auto helper(int&,int&,int&);
auto test_helper(int&,int&,int&);
class Type{
int a, b, c;
public:
void method(){
helper(a,b,c);
}
};
This, however, makes the code a lot more tedious when data members are many. So, I came up with an idea to construct an helper struct that has exact data member as Type but with all data member being public, so that we'll be able to simply pass in the handle of such HelperType, maybe something like:
struct HelperType{
int a, b, c;
};
auto helper(HelperType* a);
auto test_helper(HelperType* a);
void Type::method(){
helper(static_cast<HelperType*>(this));
}
Is there any elegant approaches to construct such HelperType struct? Such as a generic wrapper or perhaps with inheritance?

I have no simple solution to create HelperType from Type (only things coming to mind involve heavy metaprogramming or macro usage). However building Type from HelperType would be quite trivial, using private inheritance. From Derived class (cppreference.com):
When a class uses private member access specifier to derive from a base, all public and protected members of the base class are accessible as private members of the derived class.
// Could be renamed "TypePrivateMembers" or "TypeData"
struct HelperType{
int a, b, c;
};
auto helper(HelperType* a);
class Type : private HelperType {
public:
// a,b,c can be accessed in Type class scope.
void method(){
helper(this);
}
};
Live demo
However, still from cppreference (emphasis mine):
Private inheritance can also be used to implement the composition relationship (the base class subobject is an implementation detail of the derived class object). Using a member offers better encapsulation and is generally preferred unless the derived class requires access to protected members (including constructors) of the base, needs to override a virtual member of the base, needs the base to be constructed before and destructed after some other base subobject, needs to share a virtual base or needs to control the construction of a virtual base. [...]
This is the recurring composition over inheritance debate. This question has already been asked many times on StackOverflow, here are a few interesting link on the topic (in general & for this specific case):
Prefer composition over inheritance ? (language agnostic)
When to use C++ private inheritance over composition?

Related

Encapsulation in header files

I have a header file with 2 classes. class A (which is a very big class) and class B that inherits class A. I don't want people to be allowed to create objects of class A or even be able to see its static members. They should only to work with class B. What is the best way of doing that.
(Generally speaking A is a "helper class")
To restrict the creation of the class, make the constructor of class A private and declare class B as a friend class. This way only B can instantiate A.
class B;
class A
{
private:
A();
friend class B;
};
The same applies to methods (static or not): make them all private and the friend statement will allow B to access A's members.
Edit: works with protected as well.
I don't want people to be allowed to create objects of class A
What you are looking for is called an "abstract base class". In C++, any class that has at least one abstract member is automatically an abstract class, there is no additional keyword like in other languages.
class A
{
public:
virtual void Test() = 0; // abstract, has no implementation
};
class B : public A
{
public:
virtual void Test() {} // not abstract, has an implementation
};
int main()
{
A a; // this will produce a compiler error.
B b; // this is fine
return 0;
}
or even be able to see its static members
Well, don't make them public. Either make them protected or private and grant friend access to your B class.

Is there a way to make all derived classes friends of one another?

And if so, in what situation might this be useful?
Or (and I imagine this is the case), why is it absolutely useless? (What other approach essentially covers the abilities afforded by such friendship, but in a safer and less-leaky way?)
I was in a situation where I almost thought I needed such a thing. I went after an entirely different design in the end, making all the class members static. I'm still curious though.
Is there a way to make all derived classes friends of one another?
The language does not provide any mechanism to specify something like this in a base class. You'll have to provide the friend declarations in every class you inherit from the base class.
I am not able to suggest anything more positive since I don't know the problem you are trying to solve.
In a comment, you said:
In my case, I needed to access sibling methods, so if B and C derive from A, I needed to call B::foo() from C::foo(). In my case these classes encapsulate different algorithms (so the Strategy pattern comes to mind...) but sometimes one algorithm would use a substantial portion of another algorithm. Yet, it didn't seem correct to derive C from B, because C doesn't really have an "is-a" relationship with B.
If C doesn't have an "is-a" relationship with B, yet C::foo() somehow needs to call B::foo(), it indicates to me that B::foo() can only use data that is common to both B and C. In that case, it should be possible to factor out the code into a non-member function and then use it from B::foo() and C::foo().
Change the dependency from:
B::foo()
^
|
C::foo()
to
<some namespace>::foo()
^
|
+-------+---------+
| |
B::foo() C::foo()
C++ only gives you two ways to name friends:
friend class C; // a specific class
template <typename T>
friend class S; // friend the class template S
There's no way to stick in a metafunction in there, which would look hypothetically something like this:
template <typename T>
friend enable_if_t<std::is_base_of<Base, T>::value, T>;
But I guess if you're open to horrible hackery (this phrase should be interpreted as never do this ever please god no, but it's at least marginally amusing), you could simply implement all of your derived types as explicit specializations of some template.
struct Base { ... };
template <typename > class Derived;
struct A_tag { };
template <>
class Derived<A_tag> : Base {
template <typename T>
friend class Derived;
...
};
using A = Derived<A_tag>;
If we do similar thing for B, C, etc., then A, B, and C are mutually all friends - since under the hood they're really Derived<A_tag>, Derived<B_tag>, and Derived<C_tag> and thus the friend class template statement covers all of them.
Not friend exactly, but you may be able to restrict access using some variant of the Passkey pattern
If you create a protected inner Passkey class in your base class. Any derived classes can then restrict access to siblings by requiring the Passkey as a parameter:
class A {
protected:
class Passkey {};
};
class B : public A {
public:
void someProtectedFunction(Passkey) {};
};
class C : public A {
public:
void somePublicFunction() {
B b;
b.someProtectedFunction(A::Passkey{});
}
};
int main() {
C c;
c.somePublicFunction();
B b;
//b.someProtectedFunction(A::Passkey{}); // error: `class A::Passkey` is protected
}

Calling a protected method for a member object in C++

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.

Private Inheritance or Containment

I have a base class with several public methods and want to derive a child class which inherits only certain functions, so I derived the child class using private inheritance. Also I vave come across several times (including C++ primer plus) that private inheritance is almost exactly like containment. Now I have a problem where I want to use a function defined in Base to be available in the derived class.
The derived class doesn't have any private members in addition to those required by the base class. I'm not sure how to define public method "func" for derived class as shown in the code.
class Base
{
private:
double *p;
public:
Base(int m, int n);
void fun(const Base & obj1, const Base & obj2)
};
class Derived : private Base
{
public:
Derived(int n) : Base(1,n) {}
void fun(const Derived & obj1,const Base & obj2)
{
/* The function fun in derived class works almost exactly
like fun in Base class but I don't know how to call
Base.Fun(...). Also all the data needed to perform
operations in this function is a part of the private
member of the base class which the Derived member can't
access.
*/
}
}
If I were to use containment I could have just defined as follows:
class Derived
{
private:
Base P;
public:
void fun(const Derived & obj1,const Base & obj2)
{
Base :: P.func(obj1.P,obj2);
}
};
This make me wonder if containment is more appropriate here than private inheritance. On the other hand I'm not sure if either of the implementations are correct. So I'm looking for possible ways to do this.
Please note that I have not shown copy constructors,assignment and operators and some other methods in the codes above but I'm aware of their requirement. The codes are just to serve the basic purpose of showing private inheritance and containment.
If the fun method of Derived can only be implemented by directly accessing the private members of Base, neither inheritance or containment will allow Derived to access those methods. Using inheritance the member would either need to be protected (or public) or getter/setter methods that are protected (or public) would need to be added. Using composition the public getter/setter methods would be required to avoid making those data members public.
In the fun method of Derived this:
Base::fun(obj1, obj2)
will call the fun method of class Base.

C++ Functions for an Abstract Base Class

Suppose I want to have an inheritance hierarchy like this.
class Base
class DerivedOne : public Base
class DerivedTwo : public Base
The base class is not meant to be instantiated, and thus has some pure virtual functions that the derived classes must define, making it an abstract base class.
However, there are some functions that you would like your derived classes to get from your base class. These functions modify private data members that both DerivedOne and DerivedTwo will have.
class Base {
public:
virtual void MustDefine() =0; // Function that derived classes must define
void UseThis(); // Function that derived classes are meant to use
};
However, the UseThis() function is meant to modify private data members. That's where the question comes in. Should I give the Base class dummy private data members? Should I give it protected data members (and thus the derived classes won't declare their own private data members). I know the second approach will decrease encapsulation.
What is the best approach to a situation like this? If a more detailed explanation is needed I'd be happy to provide it.
If those member variables are supposed to exist in all derived classes then you should declare them in the base class. If you are worried about encapsulation, you can make them private and provide protected accessor methods for derived classes.
Another five cents: the good practice is to have abstract interface class which has no other members, but only public pure virtual methods and often public virtual destructor. Then you create base implementation which can also be abstract but can have protected fields, etc.
In you case it would be something like:
class IBlaBla;
class BlaBlaBase : public IBlaBla;
class DerivedOne : public BlaBlaBase
class DerivedTwo : public BlaBlaBase
This allows you to have more flexibility in the future if you decide that Base is no longer good for some specialized task.
Should I give the Base class dummy
private data members?
If you can implement a part of functionality without exposing the details to the derived classes, then do it in base class. If your derived classes would need access to these members, provide setters and getters. However, it is not convenient to have setters available for derived classes because your code becomes tightly coupled.
Encapsulation is sometimes overrated. If your base class and derived classes need to access those members, then they should probably be protected, not private. If it really is something that needs to be encapsulated, then you may want to make them private but provide getters and setters (either make them private to Base, with getters and setters defined there, or private to the derived classes, with pure virtual getters and setters in Base).
It's a bit hard to give you more specific advice without knowing about the actual problem you're trying to solve.
You will have to define Base::UseThis(), in the body of which you will make use of Base's fields (which you will also need to declare in the class definition above). If you only need to access them in UseThis, they can be private. If DerivedOne/Two will need access to them, you should make them protected.
Here is a possible resolution to your dilemna:
class Base {
public:
virtual ~Base() {}
virtual void redefine_me() = 0;
void utility_function();
private:
virtual int get_data_member() = 0;
virtual void set_data_member(int v) = 0;
};
class Derived1 : public Base {
public:
virtual void redefine_me() { do_d1_stuff(); }
private:
int my_private_idaho_;
virtual int get_data_member() { return my_private_idaho_; }
virtual void set_data_member(int v) { my_rpviate_idaho_ = v; }
};
class Derived2 : public Base {
public:
virtual void redefine_me() { do_d2_stuff(); }
private:
int gomer_pyle_;
virtual int get_data_member() { return gomer_pyle_; }
virtual void set_data_member(int v) { gomer_pyle_ = v; }
};
void Base::utility_function()
{
set_data_member(get_data_member() + 1);
}
It's biggest disadvantage is that now access to the private data member is mediated by a virtual function call, which isn't the cheapest thing around. It's also hidden from the optimizer.
This means that if you choose it, you should adopt a pattern where you fetch the private data member into a local variable at the beginning of your utility function and set it from the local variable before you return. Of course some utility functions may call out to functions that require the object state to be updated before they're called, and this pattern would then have to be modified to account for that. But then again, such utility functions are likely not to be able to satisfy the strong exception handling guarantee and should be rethought anyway.
It looks as if you need some interface for client code, and some 'convenient' functionality for implementors of the interface, which they can only use if they follow the rule of calling the useThis function of the convenience layer, which will tweak their private members.
Whenever I gave in to the temptation of putting the convenience functionality in my abstract base class, I regretted it (soon!) afterwards. It takes away a lot of flexibility. The solution proposed by AlexKR makes this situation slightly better.
An alternative way of doing this is providing some convenience class that implementers of the interface can aggregate instead of inheriting it. It can provide a function taking the implementer's members as arguments.
class Interface { public: virtual void f() = 0; };
class Convenience {
public:
void tweakMyMembers( int& member1, float& member2 );
bool somestate;
};
class Implementor : public Interface {
int m1; float m2;
public: Implementor( bool b ): conv( b ) {}
virtual void f() { conv.tweakMyMembers( m1, m2 ); if( m1<m2 ) dothis(); }
};