Polymorphism with a friend function in C++ - c++

I would like to combine the concepts of polymorphism and friendship. I am making a pure virtual member function of a base class a friend of another class. I would then like to override this pure virtual member function in the classes derived from that base class, and access private member data of the class who has such function as friend. See the code snippet below. The compiler complains when I refer to my_int in the derived classes member function add(). I understand friendship is a 1-to-1 relationship, but I wonder if there is any way around it so as to implement polymorphism. Do I just have to make the member functions of the different derived classes friends of the foo() class?
class foo {
private:
int my_int{};
public:
friend virtual int base::add();
};
class base {
public:
virtual int add() = 0;
};
class derived_1 : public base {
public:
int add() {
return my_int + 1;
}
};
class derived_2 : public base {
public:
int add() {
return my_int + 2;
}
}

First, with what you've displayed it's not going to work because my_int is a member of foo but in the base class tree there is no 'foo' to get the member from.
The easy answer would be to make the function take an int argument and do away with the use of friend entirely.
struct derived2 : base
{
int add(int arg) { return arg + 2; }
};
The use of 'friend' should make you seriously question whether what you are doing is a good answer, sometimes the answer to that question is 'yes' but not often. And the more friends you need the less often the answer remains 'yes'.
Another way would be to add a function to base:
int get_arg(foo & f) { return f.my_int; }
and make that function the friend rather than add, get_arg() would be called from each derived's add() in order to get the value to work with but get_arg is not itself virtual.

You might want to look here:
https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Virtual_Friend_Function
Intent
Simulate a virtual friend function.
Solution and Sample Code
Virtual friend function idiom makes use of an extra indirection to
achieve the desired effect of dynamic binding for friend functions. In
this idiom, usually there is only one function that is a friend of the
base class of the hierarchy and the friend function simply delegates
the work to a helper member function that is virtual. The helper
function is overridden in every derived class, which does the real job
and the friend function just serves as a facade.
class Base {
public:
friend ostream& operator << (ostream& o, const Base& b);
// ...
protected:
virtual void print(ostream& o) const
{ ... }
};
/* make sure to put this function into the header file */
inline std::ostream& operator<< (std::ostream& o, const Base& b)
{
b.print(o); // delegate the work to a polymorphic member function.
return o;
}
class Derived : public Base {
protected:
virtual void print(ostream& o) const
{ ... }
};

Related

Are friend functions inherited? and why would a base class FRIEND function work on a derived class object?

class baseClass {
public:
friend int friendFuncReturn(baseClass &obj) { return obj.baseInt; }
baseClass(int x) : baseInt(x) {}
private:
int baseInt;
};
class derivedClass : public baseClass {
public:
derivedClass(int x, int y) : baseClass(x), derivedInt(y) {}
private:
int derivedInt;
};
in the function friend int friendFuncReturn(baseClass &obj) { return obj.baseInt; }
I don't understand why would the friend function of the base class work for the derived class?
should not passing derived class obj. instead of a base class obj. tconsidered as error?
my question is why it works when i pass a derived class object to it?
Are friend functions inherited?
No, friend functions are not inherited.
Why would a base class function work on a derived class object?
Because friend function is using the data members available in base class only. Not the data members of derived class. Since derived class is a type of base class So, friend function is working fine. But note that here derived class instance is sliced and having information available only for base class.
friend function will report an error if you will try to access restricted members of derived class. e.g.
int friendFuncReturn(baseClass &obj) { return ((derivedClass)obj).derivedInt; }
No. You cannot inherited friend function in C++. It is strictly one-one relationship between two classes.
C++ Standard, section 11.4/8
Friendship is neither inherited nor transitive.

C++: Override method which has the same name as the class

Let's say I have a nice looking base class called base:
class base
{
public:
virtual void foo() const = 0;
};
Now, I have a class named foo that I would like to inherit from base and override base::foo:
class foo : public base
{
public:
virtual void foo() const override;
};
This is illegal in C++, as you are not allowed to name a method the same thing as the class (C++ greedily believes methods with the same name as the class are constructors, which are not allowed to have return types). Is there any way around this that doesn't involve changing the name of the class or method? I want external users to be able to create foo classes without the knowledge that there is a method base::foo called by someone else (imagine foo can be both a noun and a verb).
Is there any way around this that doesn't involve changing the name of the class or method?
No, there isn't.
All methods named foo are special in class foo -- they are constructors. Hence, they cannot be overridden virtual member functions.
I'll take a wild guess and just say NO.
You can have a lot of ambiguities in C++ (that sometimes have to be explicitly disambiguated), but I don't even see a way how a compiler or programmer could disambiguate this situation. Well, A programmer can (a function with a return type is obviously not a constructor), but C++ can't.
In C++, the only method that can have the class' name is its constructor.
So, no. You can't.
Okay, here's my (slightly evil) solution...
// Create an intermediate class which actually implements the foo method:
class foo_intermediate : public base
{
public:
virtual void foo() const override;
};
// Derive from that class and forward the constructor along
class foo : public foo_intermediate
{
public:
using foo_intermediate::foo_intermediate;
private:
friend class foo_intermediate;
// Actual implementation for the foo function goes here
void foo_impl() const;
};
// In some CPP file:
void foo_intermediate::foo() const
{
// Need to access the typename foo via namespace (global here)
static_cast<const ::foo*>(this)->foo_impl();
}
Actually calling foo is a bit funny, since this can't work:
void bar()
{
foo x;
x.foo(); // <- illegal attempt to access to the foo constructor
}
You must access through an alias:
void baz()
{
foo x;
base& rx = x;
rx.foo(); // legal
}
As an alternative, you can use a typedef:
class foo_impl : public base
{
public:
virtual void foo() const override;
};
using foo = foo_impl;
This gets around the issue of calling x.foo(), since it no longer appears as a constructor access.
I made a Gist so others could play with the two solutions if they are so inclined.

Use derived class instance as default parameter value

I need a static method of my Base class to have a default parameter value of type Derived.
Is there a way to implement this without use of overloading? (see here).
class Base;
class Derived;
Derived make_derived(void);
class Base
{
public:
static void problem_here(Base && = make_derived());
};
class Derived : public Base
{
};
Derived make_derived()
{
return Derived();
}
... gives me an error about the usage of the incomplete type Derived. How ever, I cannot place the definition of Derived in front of problem_here because it must be defined after the definition of its base class Base.
Unfortunately, returning a pointer from make_derived is not an option.
Overloading problem_here is the only thing I came up with until now, but as the "real" problem_here method takes 2 (and another one 3) parameters, and it's part of a library, this gives me ...
static void problem_here(Thing const &, Base const &);
static void problem_here(Thing const &, Base &&);
static void problem_here(Thing const &); // Default param "hack"
static void problem_here(Thing &&, Base const &);
static void problem_here(Thing &&, Base &&);
static void problem_here(Thing &&); // Default param "hack"
.. for only the two parameter case.
Is there a way to avoid writing all those function signatures, while still maintaining the same performance (no unneccessary copy/move construction for any parameter constellation) and same behaviour on the caller site?
I should add that there are multiple functions like problem_here and all need access to the protected constructor of Derived (and to those of its many siblings). So the main reason to make these methods static members of Base is to be able to friend class Base; in each of the derived classes instead of friending every function.
Refactoring showed me, that I could move the code accessing the protected constructors of the derived classes into a single factory function. That way, I'm able to move the functions with the default parameters outside Base and let the call the factory. Now I still have to friend every one of those functions, but only a single time (in Base to give them access to the factory). I could circumvent this by placing all functions into a helper class and friending it instead, but that looks like a hack to me.
class Base
{
friend class Helper; // The Hack
friend void no_problem_here(Base &&); // No hack, more writting
protected:
static void factory(Thing && from_which_I_can_construct_the_correct_derived_class);
// return type void to keep it simple, move parameter type because special cases
// handled in "trampoline" functions and a copy of the Thing must be stored either
// way.
};
class Derived : public Base
{
friend class Base;
// protected constructor omited for simplicity.
}
void no_problem_here(Base && = make_derived());
// ...
void no_problem_here(Base && b)
{
// work, and then call Base::factory
}
// or
class Helper
{
protected:
// Constructors ...
public:
static void no_problem_either(Base && = make_derived());
};
You can make declarations multiple times, so the following workaround might help:
class Base;
class Derived;
Derived make_derived(void);
class Base
{
public:
static void problem_here(Base &&);
};
class Derived : public Base {};
void Base::problem_here(Base && = make_derived()) { /* ... */ }
If there's a problem factoring the code like that, you can always insert a little trampoline function:
class Base
{
public:
static void problem_here(Base &&);
private:
static void problem_here_impl(Base &&);
};
inline void Base::problem_here(Base && x = make_derived())
{ problem_here_impl(std::move(x)); }

overriding a const method of the Base class from the derived class

class Base{
//...
public:
int get()const{ // const
// Do something.
}
int get(int x){
// Do Someting.
}
//...
};
class Derived:public Base{
//....
public:
int get(){ // not const (not the same signature as the one is the base class)
//Dosomething
}
//...
};
I know that get() in Derived class will hide get() and get(int x) methods inside Base class. so My question is:
1) is this consedred overloading or overriding ?
2) does making get() const in the derived class will change something about (hiding or not hiding Base class methods).
Quote from a c++ book:
"It is a common mistake to hide a base class method when you intend to override it, by
forgetting to include the keyword const. const is part of the signature, and leaving it off
changes the signature, and thus hides the method rather than overrides it. "
It is neither overloading nor overriding. Rather, it is hiding.
If the other function were also visible, it would be overloading, which you can achieve with using:
class Derived : public Base
{
public:
using Base::get;
int get();
};
Even if you declared int get() const in the derived class, it would merely be hiding the base function, since the base function is not virtual.
Neither, it's just "hiding".
No. Hiding occurs based on function name, not on function signature.
Your quote is only relevant if you've declared the base-class functions virtual; you cannot override a non-virtual function.
Overloading is a function named the same, but with a different signature.
Overriding is overriding a signature that already exist.
You have just "hidden", which is neither.
A quick google search reveals this:
http://users.soe.ucsc.edu/~charlie/book/notes/chap7/sld012.htm which you may find helpful.

C++: Design, Function template overriding and lack of polymorphism

Have a base class A, and a derived class B which overrides function template Func:
class A
{
A() {...};
~A() {};
template <class T>
void Func(const String &sInput, T &tResult)
{...}
};
class B : public A
{
B() {...}
~B() {};
template <class T>
void Func(const String &sInput, T &tResult)
{...}
};
(Note that Func is non-virtual, given the lack of support in C++ for templated virtual functions.)
Now have a mainprog API, class M:
class M
{
M(boost::shared_ptr<A> &pInterfaceInput): pInterface(pInterfaceInput)
{}
template <class T>
Evaluate(const String &sInput, T &tResult)
{
pInterface->Func<T>(sInput, tResult);
}
private:
const boost::shared_ptr<A> pInterface;
};
I want the function Evaluate here to support calls to functions on base class A or any of its derived classes (such as B). This class was written with polymorphism in mind before I re-designed class A and B to have templated functions.
Now the problem here is that if I pass a shared pointer of the base type to the derived type then Func of the base class will be called, not the derived class being pointed to.
How do I get around the lack of dynamic polymorphism here?
I've considered making class M a class template on the shared pointer type and having a static_cast in the constructor to ensure this type is of the base class type (A) or of a derived class.
What's the nicest way to do this? I'd prefer not to modify classes A and B to get around this problem but all suggestions are welcome.
Thanks.
Sounds like a double dispatch problem. Perhaps this would be a good place to implement the visitor pattern?
For example, create a class Evaluator, and for each T a subclass ConcreteEvaluator<T>. Give A and B methods that visit the Evaluator. Something like:
class Evaluator
{
virtual void visit_A(A* object);
virtual void visit_B(B* object);
};
template <typename T>
class ConcreteEvaluator : public Evaluator
{
public:
String* input_reference;
T& result_reference;
ConcreteEvaluator(String& input_reference_,T& result_reference_) :
input_reference(input_reference_),
result_reference(result_reference_) {}
virtual void visit_A(A* object) {
object->Func(input_reference,result_reference);
}
virtual void visit_B(B* object) {
object->Func(input_reference,result_reference);
}
}
class A
{
...
virtual void apply_evaluator(Evaluator *eval) {eval->visit_A(this);}
...
}
class B
{
...
virtual void apply_evaluator(Evaluator *eval) {eval->visit_B(this);}
...
}
For each subclass of A, a new method must be added to ConcreteEvaluator, so that this technique works best if A's class hierarchy is stable. And for each subclass of A, it must have an apply_evaluator function defined properly.
On the other hand, this may be total overkill. For about the same amount of work, you could always just pay the price to update M::Evaluate:
class M
{
...
void Evaluate(const String& sInput, T& tResult)
{
// try to downcast to each subclass of A. Be sure to check
// sub-subclasses first
try
{
dynamic_cast<B*>(pInterface.get())->Func(sInput, tResult);
return;
}
catch (std::bad_cast& ) { }
...
// nothing worked. It must really be an A
pInterface->Func(sInput,tResult);
}
...
};
I've show in the question Templatized Virtual function how to use type erasure to get some of the effects of virtual member function. Depending on what you want to do in Func(), you can use the same technique here.