Problem with implementation of Adapter Pattern - c++

I have a question - how to "convert" first interface into another using Adapter Pattern in following example? If second interface uses additional argument, I can't use this argument, if Adapter inherits from first interface (which has only one argument). What should I do?
#include <iostream>
class IFirstClass
{
public:
virtual void perform(std::string name) = 0;
};
class ISecondClass
{
public:
virtual void furtherPerform(std::string name, std::string desc) = 0;
};
class FirstClass : public IFirstClass
{
public:
virtual void perform(std::string name)
{
std::cout << "Performing action: " << name << "\n";
}
};
class SecondClass : public ISecondClass
{
public:
virtual void furtherPerform(std::string name, std::string desc)
{
std::cout << "Performing action: " << name << " with description: " << desc << "\n";
}
};
class Adapter : public IFirstClass
{
private:
SecondClass& derived;
public:
Adapter(SecondClass& derived) : derived{ derived }
{
}
virtual void perform(std::string name)
{
derived.furtherPerform(name, ? );
}
};
int main()
{
FirstClass a;
SecondClass b;
Adapter c(b);
c.perform("Name", "Description");
}

You are trying to put an adapter between interface1 and interface2, so that you can use interface2 through the adapter.
You have to make a decision on how are you going to deal with the fact that the method you need to adapt, requires more params than interface2.
a solution might be to use always a known value as a parameter (empty string, valorized string, etc).
another solution might be to pass that string into the adapter constructor
another solution might be to ask a function every time that you need to determine that value.
it really depends on what you need to adapt.

Related

Handling unique methods of Subclasses

I have a component in a software that can be described by an interface / virtual class.
Which non-virtual subclass is needed is decided by a GUI selection at runtime.
Those subclasses have unique methods, for which is makes no sense to give them a shared interface (e.g. collection of different data types and hardware access).
A minimal code example looks like this:
#include <iostream>
#include <memory>
using namespace std;
// interface base class
class Base
{
public:
virtual void shared()=0;
};
// some subclasses with shared and unique methods
class A : public Base
{
public:
void shared()
{
cout << "do A stuff\n";
}
void methodUniqueToA()
{
cout << "stuff unique to A\n";
}
};
class B : public Base
{
public:
void shared()
{
cout << "do B stuff\n";
}
void methodUniqueToB()
{
cout << "stuff unique to B\n";
}
};
// main
int main()
{
// it is not known at compile time, which subtype will be needed. Therefore: pointer has base class type:
shared_ptr<Base> basePtr;
// choose which object subtype is needed by GUI - in this case e.g. now A is required. Could also have been B!
basePtr = make_shared<A>();
// do some stuff which needs interface functionality... so far so good
basePtr->shared();
// now I want to do methodUniqueToA() only if basePtr contains type A object
// this won't compile obviously:
basePtr->methodUniqueToA(); // COMPILE ERROR
// I could check the type using dynamic_pointer_cast, however this ist not very elegant!
if(dynamic_pointer_cast<A>(basePtr))
{
dynamic_pointer_cast<A>(basePtr)->methodUniqueToA();
}
else
if(dynamic_pointer_cast<B>(basePtr))
{
dynamic_pointer_cast<B>(basePtr)->methodUniqueToB();
}
else
{
// throw some exception
}
return 0;
}
Methods methodUniqueTo*() could have different argument lists and return data which is omitted here for clarity.
I suspect that this problem isn't a rare case. E.g. for accessing different hardware by the different subclasses while also needing the polymorphic functionality of their container.
How does one generally do this?
For the sake of completeness: the output (with compiler error fixed):
do A stuff
stuff unique to A
You can have an enum which will represent the derived class. For example this:
#include <iostream>
#include <memory>
using namespace std;
enum class DerivedType
{
NONE = 0,
AType,
BType
};
class Base
{
public:
Base()
{
mType = DerivedType::NONE;
}
virtual ~Base() = default; //You should have a virtual destructor :)
virtual void shared() = 0;
DerivedType GetType() const { return mType; };
protected:
DerivedType mType;
};
// some subclasses with shared and unique methods
class A : public Base
{
public:
A()
{
mType = DerivedType::AType;
}
void shared()
{
cout << "do A stuff\n";
}
void methodUniqueToA()
{
cout << "stuff unique to A\n";
}
};
class B : public Base
{
public:
B()
{
mType = DerivedType::BType;
}
void shared()
{
cout << "do B stuff\n";
}
void methodUniqueToB()
{
cout << "stuff unique to B\n";
}
};
// main
int main()
{
shared_ptr<Base> basePtr;
basePtr = make_shared<B>();
basePtr->shared();
// Here :)
if(basePtr->GetType() == DerivedType::AType)
static_cast<A*>(basePtr.get())->methodUniqueToA();
else if(basePtr->GetType() == DerivedType::BType)
static_cast<B*>(basePtr.get())->methodUniqueToB();
return 0;
}
You can store an enum and initialize it at the constructor. Then have a Getter for that, which will give you the Type. Then a simple static cast after getting the type would do your job!
The goal of using polymorphism for the client is to control different objects with a single way. In other words, the client do not have to pay any attention to the difference of each object. That way, checking the type of each object violates the basic goal.
To achieve the goal, you will have to :
write the concrete method(methodUniqueToX()).
write a wrapper of the concrete method.
name the wrapper method abstract.
make the method public and interface/abstract.
class Base
{
public:
virtual void shared()=0;
virtual void onEvent1()=0;
virtual void onEvent2()=0;
};
// some subclasses with shared and unique methods
class A : public Base
{
private:
void methodUniqueToA()
{
cout << "stuff unique to A\n";
}
public:
void shared()
{
cout << "do A stuff\n";
}
void onEvent1()
{
this.methodUniqueToA()
}
void onEvent2()
{
}
};
class B : public Base
{
private:
void methodUniqueToB()
{
cout << "stuff unique to B\n";
}
public:
void shared()
{
cout << "do B stuff\n";
}
void onEvent1()
{
}
void onEvent2()
{
methodUniqueToB()
}
};

Redefinition of virtual method outside of class declaration C++

I am trying to use a public C++ library and extend it for my purposes. To extend it, I need to change a single virtual method within a single class. The method I am trying to override is part of an inherited class. I posted essentially what I need to do in the code below. I don't really want to rename the function because it is used in a multitude of other places and I don't want to change the source code of the library because it works for some cases, but not mine specifically.
#include <iostream>
class Base {
public:
virtual void getName() = 0;
};
class Dynamic : public Base {
public:
virtual void getName() {
std::cout << "Wrong answer\n";
}
};
//Error in redefinition of class method
void Dynamic::getName() {
std::cout << "Right answer\n";
}
int main()
{
Dynamic mydynam;
mydynam.getName();
}
Here is the code example based on the comments above.
The MyDynamic class is derived from the Dynamic class with the function re-implementation.
It will give you the right answer.
#include <iostream>
class Base {
public:
virtual void getName() = 0;
};
class Dynamic : public Base {
public:
virtual void getName() {
std::cout << "Wrong answer\n";
}
};
////////////////////////
class MyDynamic : public Dynamic {
public:
void getName() {
std::cout << "Right answer\n";
}
};
int main()
{
MyDynamic mydynam;
mydynam.getName();
}

C++ can't access child property from parent

Can anybody explain why Driver init() method is unable to print name property overridden in child?
#include <iostream>
#include <string>
class Driver {
public:
std::string name = "Unknown";
void init() {
std::cout << name << std::endl;
}
};
// need public here to inherit init()
class SpecificDriver : public Driver {
public:
std::string name = "Specific";
};
int main() {
Driver d;
SpecificDriver sd;
// this gives Unknown Unknown =/
d.init();
sd.init();
}
This gives:
Unknown
Unknown
And should be:
Unknown
Specific
Live Demo
You are not doing quite what you think you may be. You are declaring a variable "name" in driver and a variable "name" in SpecificDriver. When you call init() defined in base class driver, that driver can only access its own name field with value "unknown".
Instead you should initialize the "name" variable using a constructor.
Like this:
class Driver {
public:
std::string name;
Driver():name("Unknown"){} //default
Driver(std::string value):name(value){}
void init() {
std::cout << name << std::endl;
}
};
// need public here to inherit init()
class SpecificDriver : public Driver {
public:
SpecificDriver():Driver("Specific"){}
};
int main() {
Driver d;
SpecificDriver sd;
d.init();
sd.init();
}
Edit: Live Demo http://coliru.stacked-crooked.com/a/c453758867454348
In C++, virtual inheritance is opt-in and not implicit.
When you have this code
class Driver {
public:
std::string name = "Unknown";
void init() {
std::cout << name << std::endl;
}
};
the symbol name will be resolved statically based on what is in scope at that time.
If you later declare a global variable name it has no effect on the meaning of this code. If you later derive from this class Driver, the init function when it is inherited for that class, won't have a different meaning, as in your example.
This "static" dispatch is the default behavior in C++ because it is the simplest and fastest. Especially, it is important that it works this way if you are doing things with templates and inheritance later, otherwise lots of code would have lots of extra overhead.
Alex Zywicki shows one way that you could achieve what you want. Another way would be to use virtual dispatch to get the string. Something like this:
class Driver {
public:
virtual std::string name() const {
return "Unknown";
}
void init() {
std::cout << name() << std::endl;
}
};
class SpecificDriver : public Driver {
virtual std::string name() const override {
return "Specific";
}
};
It is possible to access the class member of the child class through CRTP.
#include <iostream>
template <typename Derived>
class Driver {
public:
void init() {
std::cout << static_cast<Derived*>(this)->name << std::endl;
std::cout << Derived::value << std::endl;
}
};
class SpecificDriver : public Driver<SpecificDriver> {
public:
std::string name = "Specific";
static constexpr char* value = "Another specific string";
};
int main() {
SpecificDriver g;
g.init();
}
If you need a common base class for storing these in, or combining with normal polymorphic behavior you can make the template class Driver inherit from a common base class.

How to implement two interfaces having the same function [duplicate]

I have something like that (simplified)
class A
{
public:
virtual void Function () = 0;
};
class B
{
public:
virtual void Function () = 0;
};
class Impl : public A , public B
{
public:
????
};
How can I implement the Function () for A and the Function() for B ?
Visual C++ lets you only define the specific function inline (i.e. not in the cpp file),
but I suppose it's an extension. GCC complains about this.
Is there a standard C++ way to tell the compiler which function I want to override?
(visual c++ 2008)
class Impl : public A , public B
{
public:
void A::Function () { cout << "A::Function" << endl; }
void B::Function () { cout << "B::Function" << endl; }
};
Thank you!
You cannot use qualified names there. I you write void Function() { ... } you are overriding both functions. Herb Sutter shows how it can be solved.
Another option is to rename those functions, because apparently they do something different (otherwise i don't see the problem of overriding both with identical behavior).
I can suggest another way to resolve this issue. You can add wrapper Typed which changes Function signature by adding dummy parameter. Thus you can distinguish methods in your implementation.
class A {
public:
virtual void Function() = 0;
virtual ~A() = default;
};
class B {
public:
virtual void Function() = 0;
virtual ~B() = default;
};
template<typename T>
class Typed : public T {
public:
virtual void Function(T* dummy) = 0;
void Function() override {
Function(nullptr);
}
};
class Impl : public Typed<A>, public Typed<B> {
public:
void Function(A* dummy) override {
std::cerr << "implements A::Function()" << std::endl;
}
void Function(B* dummy) override {
std::cerr << "implements B::Function()" << std::endl;
}
};
The benefit of such solution is that all implementation are placed in one class.
As a workaround, try
struct Impl_A : A
{
void Function () { cout << "A::Function" << endl; }
};
struct Impl_B : B
{
void Function () { cout << "B::function" << endl; }
};
struct Impl : Impl_A, Impl_B {};
If A and B are interfaces, then I would use virtual derivation to "join" them (make them overlap). If you need different implementations for your Function if called through a pointer to A or to B then I would strongly recommend to choose another design. That will hurt otherwise.
Impl "derives from" A and B means Impl "is a" A and B. I suppose you do not mean it.
Impl "implements interface" A and B means Impl "behaves like" A and B. then same interface should mean the same behavior.
In both cases having a different behavior according to the type of pointer used would be "schizophrenic" and is for sure a situation to avoid.

C++ Double Dispatch problems

This is part 2 to a problem I previously asked: Is it possible to have polymorphic member overloading in C++?
Using the Wiki example I created this example.
http://en.wikipedia.org/wiki/Double_dispatch
My problem is that the compiled code never looks up the vtable, and always uses the base instead of the inherited class. Here is my code:
#include <iostream>
class xEntity;
class xVehicle;
class xMapObject
{
public:
virtual void Bump(xMapObject&) { std::cout << "MapObject Bump MapObject\n"; };
virtual void Bump(xEntity&) { std::cout << "MapObject Bump Entity\n"; };
virtual void Bump(xVehicle&) { std::cout << "MapObject Bump Vehicle\n"; };
};
class xEntity : public xMapObject
{
public:
virtual void Bump(xMapObject&) { std::cout << "Entity Bump MapObject\n"; };
virtual void Bump(xEntity&) { std::cout << "Entity Bump Entity\n"; };
virtual void Bump(xVehicle&) { std::cout << "Entity Bump Vehicle\n"; };
};
class xVehicle : public xEntity
{
public:
virtual void Bump(xMapObject&) { std::cout << "Vehicle Bump MapObject\n"; };
virtual void Bump(xEntity&) { std::cout << "Vehicle Bump Entity\n"; };
virtual void Bump(xVehicle&) { std::cout << "Vehicle Bump Vehicle\n"; };
};
int main(int argv, char **argc)
{
xEntity Entity;
xVehicle Vechile;
xMapObject &EntityRef = Entity;
xMapObject &VehicleRef = Vechile;
VehicleRef.Bump(EntityRef);
return 0;
}
However, the output is always:
Vehicle Bump MapObject
Any help on this mystery is greatly appreciated.
You only did single dispatch, not double dispatch. The idea is that in xVehicle, taking an xMapObject&, you would call ref.bump(*this); which is double dispatch.
It is using the vtable; that's why it's calling xVechicle::Bump()! The vtable isn't used on arguments, that doesn't make sense (in C++, at least).
The typical solution is to have e.g. Bump(xMapObject& obj) call obj.Bump(*this);.
Is a bad design the xEntity::Bump(xVehicle&) because you are using as parameter in a base class a derived class.
and at least that your contract change, you don't need redefine base Bump methods.
the problem is that you are creating the xMapRef vars, that convert your derived class to a base class.
if you want that appropriated method is called, just call with the derived class object