An alternative to friend when overloading >>? - c++

In the situation below, is there any alternative to using friend? I would like to preserve all functionality of overloading the operator >>. I do not want to have public accessors in the reader class.
struct FunctorBase
{
virtual ~FunctorBase(){}
virtual void operator()(Reader &reader) const = 0;
};
//does specific stuff related to the purpose of end.
struct end : FunctorBase
{
void operator()(Reader &reader) const
{
//work with private data in reader
}
};
class Reader
{
friend class end; //I want to get rid of this if possible without losing the
//functionality of operator>> or providing accessors
Reader& operator>>(const FunctorBase &functor)
{
functor(*this);
return *this;
}
};
Any help is appreciated.
EDIT: I plan on having multiple derived classes of FunctorBase, thus multiple friend declarations. Isn't this abusing the concept of friend?

I guess the best solution depends on what end has to do with Reader.
Did you think about a base class with private inheritance (kind of interface)? You'll expose only what you need and it won't be accesible to others. Just as example:
class ReaderInterface
{
public:
void method()
{
}
};
// This is your "end" class, derived from FunctorBase,
// the consumer of ReaderInterface
class Consumer
{
public:
Consumer(ReaderInterface readerInterface)
{
readerInterface.method();
}
};
class Reader : private ReaderInterface
{
public:
void test()
{
Consumer consumer(*this);
}
};

Related

Supporting custom hooks in existing cpp class

I am designing support for custom hooks in existing C++ class.
class NotMyClass {
public:
void DoSomething() {
// Needs custom logic here.
hook_.DoSomethingCustom();
}
protected:
Hook hook_;
int not_my_class_inner_variable_1_;
Node not_my_class_inner_variable_2_;
...... More Class vars.....
}
class Hook {
public:
void DoSomethingCustom() {
// Some custom logic that needs to access not_my_class_inner_variable_1_, not_my_class_inner_variable_2 etc. .
}
}
Adding some more context here after initial comments: NotMyClass class is autogenerated and no custom logic can be added to this class. We want to be able to add custom hooks inside the autogenerated classes. So the plan was to instead pass/ingect in a Hook class that will be able to provide some custom processing. The autogenerated NotMyClass class will have hook_. DoSomethingCustom().
What's the best way to access NotMyClass member variables inside Hook ?
I don't want to change the class structure(that is use inheritence) of NotMyClass due to additional constraints.
Is making Hook a friend of NotMyClass a good option and then passing NotMyClass as this to Hook functions ?
Thanks in advance!
The problem cannot be solved as stated, i.e., without breaking the Open-Closed-Principle (OCP), which says that "classes (and other things) should be open for extension but closed for modification." In this case, this means that you shouldn't try to both (a) leave MyClass unchanged and (b) access its private or protected members from outside. Private (or protected) signal things that are not accessed from the outside, that's literally what private (or protected) are designed for. You can circumvent this (old ways, new ways) but you shouldn't.
The answer by sanitizedUser modifies MyClass, which is undesirable as per the question. A hacky but straight-forward suggestion to your problem might be to pass the fields to be modified explicitly to the method by reference:
class MyClass {
public:
void DoSomething() {
// Pass references to the fields you want to modify.
hook_.DoSomethingCustom(my_class_inner_variable_1_, my_class_inner_variable_2_);
}
protected:
Hook hook_;
int my_class_inner_variable_1_;
Node my_class_inner_variable_2_;
}
class Hook {
public:
void DoSomethingCustom(int &inner_variable_1, Node& inner_variable_2_) {
// Use the data members.
}
}
To signal that your Hook class explicitly is allowed to access members of MyClass, you could declare it as a friend. Example:
#include <iostream>
class Node {};
class MyClass;
class Hook {
public:
void DoSomethingCustom(MyClass &m);
};
class MyClass {
friend Hook; // Allows the Hook class to access our members!
public:
MyClass(Hook h): hook_(h) {}
void DoSomething() {
// Pass references to the fields you want to modify.
hook_.DoSomethingCustom(*this);
}
void print_my_class_inner_variable_1_() {
std::cout << my_class_inner_variable_1_ << std::endl;
}
protected:
Hook hook_;
int my_class_inner_variable_1_;
Node my_class_inner_variable_2_;
};
void Hook::DoSomethingCustom(MyClass &m) {
// Allowed to access private member because we are a friend!
m.my_class_inner_variable_1_ = 42;
}
int main() {
MyClass c{Hook{}};
c.print_my_class_inner_variable_1_();
c.DoSomething();
c.print_my_class_inner_variable_1_();
}
Note: your whole design with this "Hook" looks very weird to me. How do you "add hooks" to this thing (which imho is one of the defining requirements for calling something a "hook")? I'm sure if you posted a lot more context, people here would suggest a very different larger-scale design.
It's not an ideal solution but if you are allowed to declare the Hook class a friend of NotMyClass then the following code somewhat works.
#include <iostream>
class NotMyClass;
class Hook {
public:
void DoSomethingCustom(const NotMyClass& c);
};
class NotMyClass {
friend Hook;
public:
void DoSomething() {
hook_.DoSomethingCustom(*this);
}
protected:
Hook hook_;
int not_my_class_inner_variable_1_;
// Commenting Node member out because the definition of it is missing.
// Node not_my_class_inner_variable_2_;
};
void Hook::DoSomethingCustom(const NotMyClass& c) {
std::cout << c.not_my_class_inner_variable_1_ << '\n';
}
int main() {
NotMyClass{}.DoSomething();
return 0;
}
Output.
0
If you can modify NotMyClass entirely then I advice you to use polymorphism and declare Hook as an abstract class. This way its behaviour can be swapped more easily.
#include <iostream>
#include <string>
template<class State>
struct Hook {
virtual State run(const State& s) const = 0;
};
struct ExampleState {
int number;
std::string text;
};
std::ostream& operator<<(std::ostream& stream, const ExampleState& state) {
stream << state.number << ", " << state.text << '\n';
return stream;
}
struct ExampleHook : public Hook<ExampleState> {
ExampleState run(const ExampleState& s) const override;
};
class Receiver {
public:
void DoSomething();
Receiver(const Hook<ExampleState>* const hook);
private:
const Hook<ExampleState>* const hook;
ExampleState state;
};
ExampleState ExampleHook::run(const ExampleState& s) const {
// Returning a modified state.
return {
s.number + 1,
"Modified " + s.text
};
}
void Receiver::DoSomething() {
std::cout << "Original state:\n" << this->state;
this->state = this->hook->run(this->state);
std::cout << "Modified state:\n" << this->state;
}
Receiver::Receiver(const Hook<ExampleState>* const hook)
: hook(hook), state{0, "hello"} {}
int main() {
ExampleHook hook;
Receiver receiver(&hook);
receiver.DoSomething();
return 0;
}
Output.
Original state:
0, hello
Modified state:
1, Modified hello
One way of doing this is declaring data members of class MyClass public and then passing a reference to an instance of MyClass to an instance of Hook.
class MyClass {
public:
void DoSomething() {
// Pass a reference to this.
hook_.DoSomethingCustom(*this);
}
public:
Hook hook_;
int my_class_inner_variable_1_;
Node my_class_inner_variable_2_;
}
class Hook {
public:
void DoSomethingCustom(const MyClass& c) {
// Use the data members.
auto& ref1 = c.my_class_inner_variable_1_;
auto& ref2 = c.my_class_inner_variable_2_;
}
}
If you cannot declare the members public because this is a legacy code, then there is always the evil option.
#define protected public
// Your code.
#undef protected
However, if this code is already compiled as a dynamic library then you are out of luck.

Namespace Functions within Class alternatives?

I'd like to be able to group similar functions in a class into a group so I don't need to append each name with what it's about.
I've seen this question which says that you can't have namespaces within classes. I've also seen this question which proposes using strongly typed enums. The problem here though, is that I'm not sure whether or not these enums can actually accomodate functions?
The problem contextualised:
class Semaphore
{
public:
void Set(bool State){Semaphore = State;}
bool Get(){return Semaphore;}
void Wait()
{
while (Semaphore)
{
//Wait until the node becomes available.
}
return;
}
private:
bool Semaphore = 0; //Don't operate on the same target simultaneously.
};
class Node : Semaphore
{
public:
unsigned long IP = 0; //IP should be stored in network order.
bool IsNeighbour = 0; //Single hop.
std::vector<int> OpenPorts;
//Rest of code...
};
Currently, NodeClass.Get() is how I can get the semaphore. However this introduces confusion as to what Get() actually gets. I'd like to have something akin to NodeClass.Semaphore::Get(). Otherwise I'd have to have the functions as SemaphoreSet(), SemaphoreGet(), and SemaphoreWait(), which isn't too well organised or nice looking.
I had thought of just having the Semaphore class on it's own, and instantiating it within the other classes, but if I could stick with the inheritance approach, that would be nicer.
So essentially, is it possible to access inherited methods like InheritedClass.Group::Function()?
If you really want to do this, you could force the user to call with the base class name by deleteing the member function in the subclass:
class Base {
public:
void Set(bool) { }
};
class Derived : public Base {
public:
void Set(bool) = delete;
};
int main() {
Derived d;
// d.Set(true); // compiler error
d.Base::Set(true);
}
However, if the semantics of calling Set on the subclass are significantly different than what you'd expect them to be when calling Set on the base class, you should probably use a data member and name a member function accordingly as you've described:
class Base {
public:
void Set(bool) { }
};
class Derived {
public:
void SetBase(bool b) {
b_.Set(b);
}
private:
Base b_;
};
int main() {
Derived d;
d.SetBase(true);
}

Design test with templates and inheritance

I have a question regarding a design in C++.
As you see in the code below there is a design problem. I want to be able to have a TestClass which inherits from zero or more classes derived from ModeBase (ModeOne and ModeTwo in this example). If TestClass inherits from ModeOne, it would have the ability to use MethodeOne(), and it would be a requirement for TestClass to implement MethodOne() which is what I want.
class ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeBase() = default;
};
class ModeOne : private ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeOne() = default;
virtual void MethodOne() {}
};
class ModeTwo : private ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeTwo() = default;
virtual void MethodTwo() {}
};
class TestBase
{
//--Methods--------------------------------------------------------------------
public:
TestBase() : currentMode_( nullptr ) {}
virtual ~TestBase() = default;
template <class Mode, class T>
void ChangeMode()
{
if( std::is_base_of<Mode, T>::value )
{
// Class does inherit from Mode so we make sure the current mode
// has changed
currentMode_ = std::make_shared<Mode>();
}
else
{
// Class does not inherit from Mode so we don't do anything
}
}
template <class Mode>
bool CurrentMode()
{
if( std::dynamic_pointer_cast<Mode>(currentMode_) != nullptr )
{
return true;
}
return false;
}
//--Data members---------------------------------------------------------------
private:
std::shared_ptr<ModeBase> currentMode_;
};
class TestOne
: public TestBase
, private ModeOne
, private ModeTwo
{
//--Methods--------------------------------------------------------------------
~TestOne() = default;
void HeartbeatTick()
{
if( CurrentMode<ModeOne>() )
{
MethodOne();
}
else if( CurrentMode<ModeTwo>() )
{
MethodTwo();
}
}
virtual void MethodOne() {}
virtual void MethodTwo() {}
};
class SomeManager
{
~SomeManager() = default;
void ChangeAllMode()
{
for( auto it = vector_.begin(); it != vector_.end(); ++it )
{
// Here is the problem with this implementation. I need to know
// the type of the TestBase derived class (TestOne) to use it as
// a `ChangeMode` method template parameter.
//(*it)->ChangeMode<AIModeFollowLine, SOMETYPE>();
}
};
std::vector<std::shared_ptr<TestBase>> vector_;
};
I already know this is bad design since vector_ will be filled at runtime so I have no way of using ChangeMode like that. It appears that it would be a good solution to use multimethods, wouldn't it ? If so, what would the design look like ?
Multimethods (AKA multiple dispatch) deals with the issue of dispatching a call to a single function based on the runtime type of the parameters involved. This does not appear to be your issue (or have I misunderstood you?), as you have two different method names, implemented on two different types.
Your goal appears to be to select a method implementation based on a runtime type that you have injected into a class. It is not clear whether you are able to dictate the form which that injection takes but if you are then why do you not directly inject the implementation? Then you could use an implicit interface rather than an explicit one. In other words why not inject a functor-like object?
class TestBase
{
public:
typedef std::function<void ()> Ticker;
TestBase(Ticker hbTicker) : ticker{hbTicker} {}
void HeartbeatTick() {
ticker();
}
void setTicker(Ticker hbTicker){
ticker = hbTicker;
}
private:
Ticker ticker;
};
Seems like a lot less complicated to me if that meets your requirements.
If you really do need to implement multiple dispatch you will probably need to implement a visitor pattern on each of the parameters whose runtime type you need to determine. Not sure if that would work for multiple parameters though (I've not tried multiple parameters myself at least). Or you could use RTTI and a case statement or something like that.
I am just being stupid here !
I just have to use a different ChangeMode() method in order to know if TestBase and thus TestOne is of type ModeBase:
template<typename Mode>
bool
IsSame( TestBase* base )
{
return dynamic_cast<Mode*>(base) != nullptr;
};
template <class Mode>
void
ChangeMode()
{
if( isSame<Mode>(this) )
{
// Change the ticker method
}
else
{
}
}

Can I use boost::make_shared with a private constructor?

Consider the following:
class DirectoryIterator;
namespace detail {
class FileDataProxy;
class DirectoryIteratorImpl
{
friend class DirectoryIterator;
friend class FileDataProxy;
WIN32_FIND_DATAW currentData;
HANDLE hFind;
std::wstring root;
DirectoryIteratorImpl();
explicit DirectoryIteratorImpl(const std::wstring& pathSpec);
void increment();
bool equal(const DirectoryIteratorImpl& other) const;
public:
~DirectoryIteratorImpl() {};
};
class FileDataProxy //Serves as a proxy to the WIN32_FIND_DATA struture inside the iterator.
{
friend class DirectoryIterator;
boost::shared_ptr<DirectoryIteratorImpl> iteratorSource;
FileDataProxy(boost::shared_ptr<DirectoryIteratorImpl> parent) : iteratorSource(parent) {};
public:
std::wstring GetFolderPath() const {
return iteratorSource->root;
}
};
}
class DirectoryIterator : public boost::iterator_facade<DirectoryIterator, detail::FileDataProxy, std::input_iterator_tag>
{
friend class boost::iterator_core_access;
boost::shared_ptr<detail::DirectoryIteratorImpl> impl;
void increment() {
impl->increment();
};
bool equal(const DirectoryIterator& other) const {
return impl->equal(*other.impl);
};
detail::FileDataProxy dereference() const {
return detail::FileDataProxy(impl);
};
public:
DirectoryIterator() {
impl = boost::make_shared<detail::DirectoryIteratorImpl>();
};
};
It seems like DirectoryIterator should be able to call boost::make_shared<DirectoryIteratorImpl>, because it is a friend of DirectoryIteratorImpl. However, this code fails to compile because the constructor for DirectoryIteratorImpl is private.
Since this class is an internal implementation detail that clients of DirectoryIterator should never touch, it would be nice if I could keep the constructor private.
Is this my fundamental misunderstanding around make_shared or do I need to mark some sort of boost piece as friend in order for the call to compile?
You will indeed need to make some boost pieces friend for this. Basically make_shared is calling the constructor and the fact that this is done from within a friend function does not matter for the compiler.
The good news though is that make_shared is calling the constructor, not any other piece. So just making make_shared friend would work... However it means that anyone could then create a shared_ptr<DirectoryIteratorImpl>...
Is there a good reason not to use the good old shared_ptr constructor? (If there is one, you might want to take a look at the make_shared implementation and do it)
DirectoryIterator()
: impl( new detail::DirectoryIteratorImpl() )
{}
This way the call to the constructor is made from the DirectoryIterator class that is already a friend of DirectoryIteratorImpl without opening the door for all other code.
You can split your class into interface part and implementation part.
The interface part is made public, and the implementation part can have public constructors.
However, that means you have to use virtual inheritance.

Public and private access for the same member functions

I have a class (class A) that is designed to be inherited by other classes written by other people.
I also have another class (class B), that also inherits from A.
B has to access some A's member functions that shouldn't be accessed by other inheriting classes.
So, these A's member functions should be public for B, but private for others.
How can I solve it without using 'friend' directive?
Thank you.
EDIT: Example why I need it.
class A
{
public:
void PublicFunc()
{
PrivateFunc();
// and other code
}
private:
virtual void PrivateFunc();
};
class B : public class A
{
private:
virtual void PrivateFunc()
{
//do something and call A's PrivateFunc
A::PrivateFunc(); // Can't, it's private!
}
};
You can't. That's what friend is for.
An alternative would be to change the design/architecture of your program. But for hints on this I'd need some more context.
What you say is: there are two sets of subclasses of A. One set should have access, the other set shouldn't. It feels wrong to have only one brand of subclasses (i.e. B) 'see' A's members.
If what you mean is: only we can use this part of functionality, while our clients can't, there are other resorts.
(Functionality reuse by inheritance often corners you with this kind of problems. If you go towards reuse by aggregation, you may get around it.)
A suggestion:
// separate the 'invisible' from the 'visible'.
class A_private_part {
protected:
int inherited_content();
public:
int public_interface();
};
class B_internal : public A_private_part {
};
class A_export : private A_private_part {
public:
int public_interface() { A_private_part::public_interface(); }
};
// client code
class ClientClass : public A_export {
};
But better would be to go the aggregation way, and split the current "A" into a visible and an invisible part:
class InvisibleFunctionality {
};
class VisibleFunctionality {
};
class B {
InvisibleFunctionality m_Invisible;
VisibleFunctionality m_Visible;
};
// client code uses VisibleFunctionality only
class ClientClass {
VisibleFunctionality m_Visible;
};
Well - if you want exactly what you've described, then friend is the best solution. Every coding standard recommends not using friend but where the alternative design is more complex - then maybe it's worth making an exception.
To solve the problem without friend will require a different architecture
One solution might be to use a form of the pImpl idiom where 'B' derives from the inner implementation object, while the other clients derive from the outer class.
Another might be to place an extra layer of inheritance between 'A' and the "other clients". Something like:
class A {
public:
void foo ();
void bar ();
};
class B : public A { // OK access to both 'foo' and 'bar'
};
class ARestricted : private A {
public:
inline void foo () { A::foo (); }; // Forwards 'foo' only
};
However, this solution still has it's problems. 'ARestricted' cannot convert to an 'A' so this would need to be solved by some other "getter" for 'A'. However, you could name this function in such a way as it cannot be called accidentally:
inline A & get_base_type_A_for_interface_usage_only () { return *this; }
After trying to think of other solutions, and assuming that your hierarchy needs to be as you describe, I recommend you just use friend!
EDIT: So xtofl suggested renaming the types 'A' to 'AInternal' and 'ARestricted' to 'A'.
That works, except I noticed that 'B' would no longer be an 'A'. However, AInternal could be inherited virtually - and then 'B' could derive from both 'AInternal' and 'A'!
class AInternal {
public:
void foo ();
void bar ();
};
class A : private virtual AInternal {
public:
inline void foo () { A::foo (); }; // Forwards 'foo' only
};
// OK access to both 'foo' and 'bar' via AInternal
class B : public virtual AInternal, public A {
public:
void useMembers ()
{
AInternal::foo ();
AInternal::bar ();
}
};
void func (A const &);
int main ()
{
A a;
func (a);
B b;
func (b);
}
Of course now you have virtual bases and multiple inheritance! Hmmm....now, is that better or worse than a single friend declaration?
I think you have a bigger problem here. Your design doesn't seem sound.
1) I think the 'friend' construct is problematic to begin with
2) if 'friend' isn't what you want, you need to re-examine your design.
I think you either need to do something that just gets the job done, using 'friend' or develop a more robust architecture. Take a look at some design patterns, I'm sure you'll find something useful.
EDIT:
After seeing your sample code, you definitely need to re-arch. Class A may not be under your control, so that's a little tricky, but maybe want you want to re-do Class B to be a "has-a" class instead of an "is-a" class.
public Class B
{
B()
{
}
void someFunc()
{
A a; //the private functions is now called and a will be deleted when it goes out of scope
}
};
I find this a interesting challenge. Here is how I would solve the problem:
class AProtectedInterface
{
public:
int m_pi1;
};
class B;
class A : private AProtectedInterface
{
public:
void GetAProtectedInterface(B& b_class);
int m_p1;
};
class B : public A
{
public:
B();
void SetAProtectedInterface(::AProtectedInterface& interface);
private:
::AProtectedInterface* m_AProtectedInterface;
};
class C : public A
{
public:
C();
};
C::C()
{
m_p1 = 0;
// m_pi1 = 0; // not accessible error
}
B::B()
{
GetAProtectedInterface(*this);
// use m_AProtectedInterface to get to restricted areas of A
m_p1 = 0;
m_AProtectedInterface->m_pi1 = 0;
}
void A::GetAProtectedInterface(B& b_class)
{
b_class.SetAProtectedInterface(*this);
}
void B::SetAProtectedInterface(::AProtectedInterface& interface)
{
m_AProtectedInterface = &interface;
}
If you where going to use this sort of pattern all the time, you could reduce the code by using templates.
template<class T, class I>
class ProtectedInterfaceAccess : public I
{
public:
void SetProtectedInterface(T& protected_interface)
{
m_ProtectedInterface = &protected_interface;
}
protected:
T& GetProtectedInterface()
{
return *m_ProtectedInterface;
}
private:
T* m_ProtectedInterface;
};
template<class T, class I>
class ProtectedInterface : private T
{
public:
void SetupProtectedInterface(I& access_class)
{
access_class.SetProtectedInterface(*this);
}
};
class Bt;
class At : public ProtectedInterface <::AProtectedInterface, Bt>
{
public:
int m_p1;
};
class Bt : public ProtectedInterfaceAccess<::AProtectedInterface, At>
{
public:
Bt();
};
class Ct : public At
{
public:
Ct();
};
Ct::Ct()
{
m_p1 = 0;
// m_pi1 = 0; // not accessible error
}
Bt::Bt()
{
SetupProtectedInterface(*this);
m_p1 = 0;
GetProtectedInterface().m_pi1 = 0;
}
If I understand:
A will be subclassed by other developers.
B will be subclassed by other developers and inherits from A.
A has some methods you don't want accessible to outside developers through B.
I don't think this can be done without using friend. There is no way I know of to make members of a superclass available only to direct inheritors.