Is there no way to upcast into an abstract class and not modify it each time a class is derived from it? - c++

#include<iostream>
using namespace std;
class Abs
{
public:
virtual void hi()=0;
};
class B:public Abs
{
public:
void hi() {cout<<"B Hi"<<endl;}
void bye() {cout<<"B Bye"<<endl;}
};
class C:public Abs
{
public:
void hi() {cout<<"C Hi"<<endl;}
void sayonara() {cout<<"C Sayonara"<<endl;}
};
int main()
{
Abs *bb=new B;
bb->bye();
Abs *cc=new C;
cc->sayonara();
}//main
The compiler says
test2.cpp: In function ‘int main()’:
test2.cpp:26: error: ‘class Abs’ has no member named ‘bye’
test2.cpp:28: error: ‘class Abs’ has no member named ‘sayonara’
Because of this problem, I'll have to add functions to the Abs class each time I create a new derived class which inherits from it (Upcasting is compulsory for me to do. The program I'm planning requires it to be so). I don't want to touch the base class once it's created.
Doesn't this problem violate the principle that once you make a base class, you won't have to modify it ever. Any way to resolve this problem?
p.s: I've seen the factory design pattern and the prototype design patterns, but both of them can't seem to be able to solve it.

This is defeating the purpose of inheritance and abstract interfaces. bye and sayonara both do the same thing (saying goodbye), only in different languages. This means you should have an abstract say_goodbye method that gets overridden for subclasses. I suppose this is a simplified example, so maybe you could describe your actual scenario so we can provide more specific help.
Edit If you want to create a copy of the derived class through an abstract interface, check out this question. If you want to explicitly access the different attributes of your subclasses, you should be asking your self if subclassing es even appropriate here, since your classes don't seem to have much in common.

Well, i'm not sure to understand exactly what you want (and why you want it that way) but:
int main()
{
Abs *bb=new B;
static_cast<B*>(bb)->bye();
Abs *cc=new C;
static_cast<C*>(cc)->sayonara();
}//main
Will work.
You just have to be sure that bb is really a B* before you static_cast.
You may also use dynamic_cast which will return a null pointer if bb is not of the correct type.

int main()
{
B *bb = new B;
bb->bye();
C *cc=new C;
cc->sayonara();
}//main
This way modifications in the base class are no longer needed :)

Dynamic casting is a sensible option. If you're religious about dynamic casts, you can use the visitor design pattern:
struct Abs;
struct B;
struct C;
struct Visitor
{
virtual ~Visitor() {}
// Provide sensible default actions
virtual void visit(Abs&) const { throw "not implemented"; }
virtual void visit(B& b) const { visit(static_cast<Abs&>(b)); }
virtual void visit(C& c) const { visit(static_cast<Abs&>(c)); }
};
struct Abs
{
virtual ~Abs() {}
virtual void hi() = 0;
virtual void accept(Visitor const& v) { v.visit(*this); }
};
struct B : Abs
{
void hi() { ... }
void accept(Visitor const& v) { v.visit(*this); }
void bye() { ... }
};
struct C : Abs
{
void hi() { ... }
void accept(Visitor const& v) { v.visit(*this); }
void sayonara() { ... }
};
struct DoSayonara : Visitor
{
void visit(C& c) const { c.sayonara(); }
};
struct DoBye : Visitor
{
void visit(B& b) const { b.bye(); }
};
struct ByeOrSayonara : Visitor
{
void visit(B& b) const { b.bye(); }
void visit(C& c) const { c.sayonara(); }
};
and then you use
Abs* b = new B(); Abs* c = new C();
b->accept(DoSayonara()); // Throw an exception
c->accept(DoSayonara()); // Do what is expected
Do this only when you really need it.

If upcasting is compulsory and you need to call methods defined in the subclasses then You're Doing It Wrong.
However, at a given point in time, you either know that an object is a specific subclass, in which case you can dynamically cast to that type, or you don't and can't be sure you can call the function.
Assuming this is related to your other question, I've tried to explain a way to implement that particular problem in a different manner there.

Related

Implementing compositional behaviour for virtual methods

Suppose that I have a heirarchy of several classes:
class A {
public:
virtual void DoStuff() = 0;
};
class B : public A {
public:
// Does some work
void DoStuff() override;
};
class C : public B {
public:
// Calls B::DoStuff and does other work
void DoStuff() override;
};
It can naively be implemented:
void Derived::DoStuff() {
Base::DoStuff();
...
}
This implementation has a serious problem, I believe: one always has to remember to call base implementation when overrides.
Alternative:
class A {
public:
void DoStuff() {
for (auto& func: callbacks_) {
func(this);
}
}
virtual ~A() = default;
protected:
template <class T>
void AddDoStuff(T&& func) {
callbacks_.emplace_back(std::forward<T>(func));
}
private:
template <class... Args>
using CallbackHolder = std::vector<std::function<void(Args...)>>;
CallbackHolder<A*> callbacks_;
};
Usage:
class Derived : public Base {
public:
Derived() {
AddDoStuff([](A* this_ptr){
static_cast<Derived*>(this_ptr)->DoStuffImpl();
});
}
private:
void DoStuffImpl();
};
However, I believe that it has a good amount of overhead when actually calling DoStuff(), as compared to the first implementation. In the use cases which I saw, possibly long costruction of objects is not a problem (one might also try to implement something like "short vector optimization" if he wants).
Also, I believe that 3 definitions for each DoStuff method is a little too much boilerplate.
I know that it can be very effectively solved by using inheritance pattern simular to CRTP, and one can hide the template-based solution behind interface class (A in the example), but I keep wondering -- shouldn't there be an easier solution?
I'm interested in a good implementation of call DERIVED implementation FROM BASE, if and only if derived class exists and it has an overriding method for long inheritance chains (or something equivalent).
Thanks!
Edit:
I am aware of an idea described in #Jarod42's answer, and I don't find it appropriate because I believe that it is ugly for long inheritance chains -- one has to use a different method name for each level of hierarchy.
You might change your class B to something like:
class A {
public:
virtual ~A() = default;
virtual void DoStuff() = 0;
};
class B : public A {
public:
void DoStuff() final { /*..*/ DoExtraStuff(); }
virtual void DoExtraStuff() {}
};
class C : public B {
public:
void DoExtraStuff() override;
};
I am not sure if I understood correctly but this seems to be addressed pretty good by the "Make public interface non-virtual, virtualize private functions instead" advice.
I think it's orignated in the Open-Closed principle. The technique is as-follows:
#include <iostream>
class B {
public:
void f() {
before_f();
f_();
};
private:
void before_f() {
std::cout << "will always be before f";
}
virtual void f_() = 0;
};
class D : public B{
private:
void f_() override {
std::cout << "derived stuff\n";
}
};
int main() {
D d;
d.f();
return 0;
}
You essentially deprive descendant class of overriding public interface, only customize exposed parts. The base class B strictly enforces that required method is called before actual implementation in derived might want to do. As a bonus you don't have to remember to call base class.
Of course you could make f virtual as well and let D decide.

How to have two pure virtual methods with the same name but different return types

I've got an interface A which is publicly available, and a back-end implementation class C, like so:
struct A
{
virtual void f() = 0;
};
struct C : public A
{
virtual void f() override
{
}
};
I would like to gradually migrate to a new interface, B. B will have the same methods, however, the return types might be different. I would like my implemetation class to implement both A and B so that legacy code can keep using A until it is migrated, but new code can be written with B. I know that if I have two pure virtual methods with exactly the same signature, I only need one override in my implementation class. But if they differ by return type, I don't know how to do it...
struct A
{
virtual void f() = 0;
};
struct B
{
virtual int f() = 0;
};
struct C : public A, public B
{
// How do I implement both versions of f() here??
};
The way I would do it is
struct A {}
struct B {}
struct OldImpl : public A {}
struct NewImpl : public B {}
struct Combined : public AImpl, public BImpl {}
You can then pass the combined into anything that wants an A or a B.
The problem with this is that your OldImpl and NewImpl are completely separate. They're not allowed to interact with each other; meaning you can't call setFoo() in A and get the same value in getFoo() in B. Which is probably not what you want from what you described.
To resolve this, don't create a 2nd interface. It wouldn't work anyway because where a xxx() might be void now, and an int later, you probably want to do something with the return value. If you really want to do it in baby steps, create a branch, change a single functions return value, test it, merge it in, repeat.
Thanks for the good responses! But I did figure out my own solution: good old optional parameters!
struct A
{
virtual void f() = 0;
};
struct B
{
virtual int f(int ignoreMe = 0) = 0;
};
struct C : public A, public B
{
virtual void f() override {}
virtual int f(int) override {}
};
No ambiguity for external users using A or B, and no parameters need to change. No ambiguity internally either because parameter is non-optional in the implementation class. The optional parameter can be removed, along with A, once migration is complete.
This at least compiles with VS2017:
struct A
{
virtual void f() = 0;
};
struct A2: public A
{
void f() { Af(); }
virtual void Af() = 0;
};
struct B
{
virtual int f() = 0;
};
struct B2 : public B
{
int f() { return Bf(); }
virtual int Bf() = 0;
};
struct C : public A2, public B2
{
void Af() {}
int Bf() { return 42; }
};
Edit: Could not add this a comment on Paul Accisano's own answer, so I put it here.
Modifying Paul's answer slightly. By making the unused default parameter a protected class, you still have correct type checking, and avoid the potential for a type conflict with another member function.
struct A
{
virtual void f() = 0;
};
struct B
{
protected:
class disambiguator {};
public:
virtual int f(disambiguator ignoreMe = disambiguator()) = 0;
};
struct C : public A, public B
{
virtual void f() override {}
virtual int f(disambiguator ignoreMe) override { return 42; }
};
A *createA() { return new C; }
B *createB() { return new C; }
One application for this could be the gradual migration from raw pointers to smart pointers.

Design of a general-purpose handler for 'solver' class

A case where 'problem' should not be a problem in the title.
I want to implement a solver (class Solver) for a collection of problems (all children of class Problem), which more or less share the same set of methods. My current design is like this:
In solver.h:
template<class P>
class Solver{
public:
P* p;
Solver(P* problem) : p(problem) {}
void justDoIt(){
p->step1();
p->step2();
p->step3();
p->step4();
p->step5();
}
}
In main.cpp:
#include "solver.h"
class A {
public:
void step1() {}
void step2() {}
void step3() {}
void step4() {}
void step5() {}
};
class B: public A {
public:
void step2() {}
void step4() {}
};
class C: public A {
public:
void step3() {}
void step4() {}
void step5() {}
};
int main(){
B b;
C c;
Solver<B> sb(&b);
Solver<C> sc(&c);
sb.justDoIt();
sc.justDoIt();
return 0;
}
If I want to extend Solver for a new problem type, say C, and it
does nothing in step1();
does step2.5() between step2() and step3()
Now calling C c; Solver<C> sc(&c); c.justDoIt(), I need to modify A, B and Solver::justDoIt() first.
Is there a scalable to design the interface that adding new problem types (all childern of A) for Solver?
PS: The current codebase I am about to modify has 47 types of problems all using the same Solver class. Minimal change is preferred.
How can I do it better?
At least to me this design seems like a (pardon the technical jargon) mess.
Right now, Solver has intimate knowledge of the internals of Problem. Further, it appears there's no way for Solver to do its job without intimate knowledge of the internals of Problem either.
At least in my estimation, what you've called Solver::justDoIt() should really be Problem::operator(). If many of the Problems use step1() through step5() as you've shown in Solver, you can provide that implementation by default in Problem itself, then those that need to override that will provide their own implementations:
class Problem {
protected:
virtual void step1() {}
// ...
virtual void step5() {}
public:
virtual void operator()() {
step1();
step2();
step3();
step4();
step5();
}
};
class B : public Problem {
protected:
void step2() {}
void step4() {}
};
class C : public Problem {
protected:
virtual void step3() {}
virtual void step4() {}
virtual void step5() {}
};
Then the main looks something like this:
int main() {
B b;
C c;
b();
c();
}
Or, if you prefer shorter code:
int main() {
B()();
C()();
}
This creates a temporary object of each type, then invokes the operator() on that temporary object. I'm not particularly fond of it, but some people think it's great.
Virtual Functions:
The first option that should come into mind is to use virtual functions:
Redefine your Problem-class to contain a pure virtual function (that means: every child needs to reimplement it):
class Problem{
public:
virtual void allSteps()=0;
};
Redefine your Solver to call this special function:
class Solver{
public:
Problem* p;
Solver(Problem* prob):p(prob){}
void solve(){
p->allSteps();
}
};
And add an implementation in every child-class:
class MyProblem: public Problem{
public:
void step1(){
std::cout << "step1\n";
}
void step2(){
std::cout << "step1\n";
}
void stepx(int x){
std::cout << "step"<<x<<"\n";
}
void allSteps(){
step1();
step2();
stepx(3);
stepx(4);
}
};
And use your main-function as you did before:
int main() {
MyProblem myP;
Solver s(&myP);
s.solve();
return 0;
}
Try it here: http://ideone.com/NOZlI6
Function-Pointers/Objects
This is a slightly more complex solution, but depending on your needs (e.g. executing only a single step and then do something else) it might better fit your needs.
Whenever you see something like "foo1","foo2","foo3",... you should think of an array or a vector. And the same can be applied to your Problem:
First of all, redefine your "Problem" class to take an arbitrary amount of function pointers - or using c++, function objects:
class Problem{
public:
std::vector<std::function<void(void)>> functions;
};
Then all your Solver needs to do is to iterate over the function objects inside your Problems class:
class Solver{
public:
Problem* p;
Solver(Problem* prob):p(prob){}
void solve(){
for(auto func : p->functions)
func();
}
};
In order to register your classes functions properly, you need to remember that member-functions have an additional "hidden" parameter "this" that is a pointer to the class itself. But we can use std::bind to make a void(void) function out of any function we have. An alternative would be to use static functions, but since this should be easy to figure out, i will use the more complex way here:
class MyProblem: public Problem{
public:
void step1(){
std::cout << "step1\n";
}
void step2(){
std::cout << "step1\n";
}
void stepx(int x){
std::cout << "step"<<x<<"\n";
}
MyProblem(){
functions.push_back(std::bind(&MyProblem::step1,this));
functions.push_back(std::bind(&MyProblem::step2,this));
functions.push_back(std::bind(&MyProblem::stepx,this,3));
functions.push_back(std::bind(&MyProblem::stepx,this,4));
}
};
Your main-function will then be unaffected:
int main() {
MyProblem myP;
Solver s(&myP);
s.solve();
return 0;
}
Try it here: http://ideone.com/BmIYVa

Virtual function with fixed implementation not using most derived class for (*this)

Let's say I have the following code:
struct Z;
struct A
{
virtual void Do (Z & z) const;
};
struct B : public A {};
struct Z
{
void use (A const & a) {}
void use (B const & b) {}
};
void A::Do(Z& z) const{
z.use(*this);
}
Right now, when I call B.do, the type of this is A, which make sense, because the implementation of do is defined in A.
Is there any way to have calls to B.do use use (B const &) without having to copy-paste the same code for do from A into B? In my actual code I have about 15 (and growing) classes derived from some base class and it seems a waste having to copy-paste the identical code for do everytime.
[Edit] Clarification: all Do does is call use, nothing else. Do and use are the accept & visit functions from the Visitor pattern.
Since you now clarified that what you want is the visitor pattern, well, sorry, but that's just how it is. This answer shows how the visitor pattern with double dispatch works.
I thought of a nice way using CRTP, but this may or may not work for you, depending on the circumstances.
(Note: I used the code from the linked answer, so the names don't match, but I hope you get the idea.)
// your Z
class Visitor;
// superclass needed for generic handling
struct Superbase{
virtual void Accept(Visitor& v) = 0;
};
// your A
template<class Der>
class Base : public Superbase{
public:
void Accept(Visitor& v){
v.Visit(static_cast<Der&>(*this));
}
};
// your B
class Derived1 : public Base<Derived1> {
};
// new C
class Derived2 : public Base<Derived1> {
};
class Visitor {
public:
virtual void Visit(Superbase& sup){
// generic handling of any Superbase-derived type
}
virtual void Visit(Derived1& d1){
// handle Derived1
}
virtual void Visit(Derived2& d2){
// handle Derived1
}
};
int main(){
Visitor v;
Derived1 d1;
d1.Accept(v);
}
The only problem: Now you're missing the chance to have a generic handle to any type of A, since functions can't be both virtual and templates. :|
Scrape that, found a solution using a Superbase base class. :) This even allows you to have a container of Superbases and take full advantage of polymorphism. :)
I think this code does what you want:
#include <iostream>
struct A;
struct B;
struct Z
{
void use (A const & a);
void use (B const & b);
};
template<typename DERIVED>
struct XX
{
void Do(Z& z){
Do(z,THIS());
}
private:
const DERIVED& THIS() const { return static_cast<const DERIVED&>(*this); }
void Do(Z& z, const DERIVED& t){
z.use(t);
}
};
struct A : public XX<A> {};
struct B : public XX<B> {};
void Z::use (A const & a) { std::cout << "use for A" << std::endl; }
void Z::use (B const & b) { std::cout << "use for B" << std::endl; }
int main(){
A a;
B b;
Z z;
a.Do(z);
b.Do(z);
return 0;
}
The only 'maintenance' or 'boiler-plate' part of the code is to derive from the template class templated on your own type.
You need to dispatch the call of use based on the type pointed to by this so you need to add another virtual function to A and B that simply invokes the correct use. I assume that do does other things than call use of course otherwise you would indeed have to re-implement do in each subclass. It would look like this
struct A
{
virtual void Do (Z & z) const
{
// do stuff
use(z);
// do more stuff
}
virtual void use(Z & z) const
{
z.use(*this);
}
};
struct B : public A
{
virtual void use(Z & z) const
{
z.use(*this);
}
};
struct Z
{
void use (A const & a) {}
void use (B const & b) {}
};
I think I have to disappoint you and say no. This is the trade off you have to make, in order for you to break out the interface from your classes into the visitor. The visitor must know which one is reporting to it, as long as you don't override the virtual Do() in the base class, the visitor will treat you as A.
Please someone prove me wrong! (I'd also see this solved to remove redundancy)

Passing around base class pointers

Scenario: I have the following defined classes.
class Baseclass { };
class DerivedTypeA : public Baseclass { };
class DerivedTypeB : public Baseclass { };
// ... and so on ...
class Container
{
list<Baseclass*> stuff;
list<DerivedTypeA*> specific_stuff;
// ... initializing constructors and so on ...
public:
void add(Baseclass * b)
{
stuff.add(b);
}
void add(DerivedTypeA * a)
{
stuff.add(a);
specific_stuff.add(a);
}
};
class ContainerOperator
{
Container c;
// ... initializing constructors and so on ...
public:
void operateOnStuff(Baseclass * b)
{
// This will always use "void add(Baseclass * b)" no matter what object b really is.
c.add(b);
}
};
// ...
containerOperator.operateOnStuff(new DerivedTypeA());
So, what I want to do is to handle a certain derived class in some special way in Container.
Problem: void add(DerivedTypeA * a) is never called. I'm obviously doing something wrong. What is the correct way of doing what I am trying to achieve here?
Overload resolution in C++ happens at compile-time, not run-time. The "usual" way to solve problems like this is to use Visitor pattern.
You can reduce the amount of boilerplate copy-paste by implementing Visitor with CRTP.
If you use CRTP for Base::accept, you don't need to define it any more in derived classes.
Here is a similar program to yours, but a little simpler:
#include <iostream>
class Base; class Derived;
struct Operation {
void add(Base *b) {
std::cout << "Base\n";
}
void add(Derived *b) {
std::cout << "Derived\n";
}
void visit(Base *b); // need to define this after Base class
};
struct Base {
virtual ~Base() {}
virtual void accept(Operation &o)
{
o.add(this);
}
};
void Operation::visit(Base *b) {
b->accept(*this);
}
struct Derived : public Base {
void accept(Operation &o)
{
o.add(this);
}
};
int main() {
Operation o;
Base b;
Derived d;
Base *ptrb = &b;
Base *ptrd = &d;
o.add(ptrb); // These two print "Base"
o.add(ptrd);
o.visit(ptrb); // "Base"
o.visit(ptrd); // "Derived"
}
You can use RTTI to determine whether the provided object is of the derived type, and if so, call the second add() function.
void add(Baseclass * b)
{
stuff.add(b);
DerivedTypeA * a = dynamic_cast<DerivedTypeA *>(b);
if ( a != 0 )
specific_stuff.add(a);
}
Unlike the visitor pattern this solution violates the Open-Closed Principle, but it's a lot simpler and easier to understand when the number of derived classes do not change or change slowly over time.