Suppose I wrote some code like this:
// myinterface.h
struct MyInterface { void foo()=0; };
// mydefault.h
#include "myinterface.h"
struct MyDefaultImplementation : MyInterface { void foo(){} };
// main.cpp
#include "myinterface.h"
#include "mydefault.h" // (X)
int main(){
MyInterface* x = new MyDefaultImplementation(); // (X)
x->foo();
}
I can provide a different implementation of the interface easily, but I need to change the lines where I create the instance and of course the include (X).
Is it possible to replace the implementation of the interface without changing existing code?
Just to clarify: of course with the above code it is not possible, but can I change it somehow, such that later when I want to switch to another implementation of the interface I dont have to change it?
The closest I could find is this, but thats java :(
Btw the example is very much simplified, but also in my actual code, there is only a single line in the code, where I create the instance.
Use a factory approach, eg:
myinterface.h
struct MyInterface
{
virtual ~MyInterface() {}
virtual void foo() = 0;
};
MyInterface* createMyInterface();
main.cpp
#include "myinterface.h"
int main()
{
MyInterface* x = createMyInterface();
x->foo();
delete x;
}
Then you can make createMyInterface() create whatever struct type you need, eg:
mydefault.h
#include "myinterface.h"
struct MyDefaultImplementation : MyInterface
{
void foo(){}
};
myinterface.cpp
#include "mydefault.h"
MyInterface* createMyInterface()
{
return new MyDefaultImplementation;
}
Related
The users of a class need not see the private members of that class. Those members may introduce new types the users should not be aware of, requiring #include of files to declare those types. I would like to get rid of these #include. I would prefer declaring these private members of the class, in a separate .hpp file that is seen only by the implementation of the class.
Is there a way doing this ?
I'm afraid it is not possible as the client class has probably to know the size of an instance of that class, then must have access to its full declaration. This unfortunately adds useless dependances.
You would usually use the pimpl idiom for this:
// --------------------
// interface (widget.h)
class widget
{
widget();
void exampleFunction();
private:
struct impl;
std::unique_ptr<impl> pImpl;
};
// ---------------------------
// implementation (widget.cpp)
struct widget::impl
{
// implementation details
int exampleMember;
};
widget::widget() : pImpl(std::make_unique<widget::impl>()){}
void widget::exampleFunction() {
pImpl->exampleMember++;
}
A simple pattern is this.
// IFoo.h
#pragma once
class IFoo
{
public:
virtual void DoSomethingImportant() = 0;
virtual void DoSomethingElse() = 0;
};
-----------------------
// Foo.h
#pragma once
#include "IFoo.h"
#include "MessyHeaderFilesThatPullIntooMuch.h"
class Foo : public IFoo
{
private:
ComplexStructure _internals; // stuff you don't want clients to know abouve
int _x;
int _y;
public:
virtual void DoSomethingImportant() override;
virtual void DoSomethingElse() override;
};
-----------------------
// Foo.cpp
#include "Foo.h"
void Foo::DoSomethingImportant() {Your code goes here}
void Foo::DoSomethingElse() {Your code goes here}
-----------------------
// FooFactory.h
#pragma once
#include <IFoo.h>
IFoo* CreateFoo();
-----------------------
// FooFactory.cpp
#include <FooFactory.h>
#include <Foo.h>
IFoo* CreateFoo()
{
return new Foo();
}
Then the clients who want to get at an instance of "Foo" just need to #include "FooFactory.h" to obtain a new instance of Foo via the IFoo interface pointer. And they never have to see the messy internals of Foo or take a dependency on the additional header files Foo needs. They get back just the public interface of Foo that hides all the internals.
my_func.h
class MyClass{
public:
OtherClass otherclass;
void func();
void func(OtherClass others);
};
my_func.cpp
#includ <my_func.h>
void MyClass::func(){
func(this->otherclass);
}
void MyClass::func(OtherClass others){
if(others.value.IsObject)
func(others.value);
}
main.cpp
#include <my_func.h>
int main(){
func();
}
I want to refactoring this code.
I want to set default parameter, so I write code like this.
but I think there is a better way.
I have this error for the following code
incomplete type ‘Foo::Pimpl’ used in nested name specifier
AnotherFoo.hpp
struct AnotherFoo {
void methodAnotherFoo(Foo &);
};
AnotherFoo.cpp
#include "Foo.hpp"
#include "AnotherFoo.hpp"
void AnotherFoo::methodAnotherFoo(Foo &foo) {
// here i want to save the function pointer of methodPimpl(), std::function for ex:
std::function<void(void)> fn = std::bind(&Foo::Pimpl::methodPimpl, foo._pimpl); // <-- Here i am getting the error
}
Foo.hpp
struct Foo {
Foo();
class Pimpl;
std::shared_ptr<Pimpl> _pimpl;
};
Foo.cpp
#include "Foo.hpp"
struct Foo::Pimpl {
void methodPimpl(void) {}
};
Foo::Foo() : _pimpl(new Pimpl) {}
main.cpp
#include "Foo.hpp"
#include "AnotherFoo.hpp"
int main() {
Foo foo;
AnotherFoo anotherFoo;
anotherFoo.methodAnotherFoo(foo);
}
Does anyone have a good solution for how to fix this?
The main goal that I am trying to achieve is to keep the signature of the methodAnotherFoo method hidden from the header files.
The only file in which you may access details of Foo::Pimpl is Foo.cpp, the file in which it is defined.
You may not access it in AnotherFoo.cpp.
Your choices are:
Change the implementation of AnotherFoo::methodAnotherFoo to use only the public interface of Foo.
Move the implementation of AnotherFoo::methodAnotherFoo to Foo.cpp.
If AnotherFoo.cpp needs direct access to the implementation object it is going to have to see the definition of that type, there is no way around that. Perhaps add a "detail/foo.h" header that is meant for internal use like this.
Your Pimpl implementation is not correct. It should hide details while you are trying to access them directly from methodAnotherFoo. So you should make implementation details private and provide a public proxy methods to manipulate stored implementation:
class Foo
{
public: Foo();
public: void method(void);
private: class Pimpl;
private: std::shared_ptr<Pimpl> _pimpl;
};
// Foo.cpp
struct Foo::Pimpl
{
void methodPimpl(void) {}
};
Foo::Foo() : _pimpl(new Pimpl) {}
void Foo::method(void) {_pimpl->method();}
And change the rest of the code to utilize those proxy methods instead of digging to implementation details:
void AnotherFoo::methodAnotherFoo(Foo &foo)
{
std::function<void(void)> fn = std::bind(&Foo::method, foo);
}
One solution that i found is to move the Pimpl implementation to AnotherFoo.cpp
I have a PieceStrategy class:
#include "QueenStrategy.cpp"
class PieceStrategy {
void promoteToQueen() {
this = new QueenStrategy();
}
}
And I have a QueenStrategy class which inherits from it:
#include "PieceStrategy.cpp"
class QueenStrategy : public PieceStrategy {}
Now arises the circular includes problem. But in this case, I cannot use forward declaration.
What should I do?
You should not include cpp files, but headers
You must not assign to this
Choose another design. You should not try to modify the strategy but select another one for the actual object, that uses that strategy.
piece.hpp
#include "strategy.hpp"
class Piece
{
std::unique_ptr<Strategy> strategy;
public:
static Piece Pawn();
void PromoteToQueen();
};
piece.cpp
#include "pawn.hpp"
#include "queen.hpp"
Piece Piece::Pawn()
{
Piece p;
p.strategy = std::make_unique<PawnStrategy>();
return p;
}
void Piece::PromoteToQueen()
{
strategy = std::make_unique<QueenStrategy>();
}
I'm writing a C++ wrapper library around a number of different hardware libraries for embedded systems (firmware level), using various libraries from different vendors (C or C++). The API exposed by the header files should be vendor agnostic... all Vendor header libraries are not included in any of my header files.
A common pattern I have is making the vendor member data opaque, by only using a pointer to some "unknown" vendor struct/class/typedef/pod type.
// myclass.h
class MyClass
{
...
private:
VendorThing* vendorData;
};
and implementation (note: each implementation is vendor specific; all have the same *.h file)
// myclass_for_vendor_X.cpp
#include "vendor.h"
... {
vendorData->doSomething();
or
VendorAPICall(vendorData,...);
or whatever
The problem I have is that VendorThing can be lots of different things. It could be a class, struct, type or pod. I don't know, and I don't want to care in the header file. But if you pick the wrong one, then it doesn't compile if the vendor header file is included as well as my header file. For example, if this the actual declaration of VendorThing in "vendor.h":
typedef struct { int a; int b; } VendorThing;
Then you can't just forward-declare VendorThing as class VendorThing;. I don't care about what the type of VendorThing is at all, all I want is the public interface to think of it as void * (i.e allocate space for a pointer and that is it), and the implementation think of it using the correct pointer type.
Two solutions I have come across are the "d-pointer" method found in Qt, where you add a level of indirection by replacing VendorThing a new struct VendorThingWrapper
// myclass.h
struct VendorThingWrapper;
class MyClass
{
...
private:
VendorThingWrapper* vendorDataWrapper;
};
and in your cpp file
// myclass.cpp
#include "vendor.h"
struct VendorThingWrapper {
VendorThing* vendorData;
};
... {
vendorDataWrapper->vendorData->doSomething();
}
but this adds a second pointer dereference, which is not a huge deal, but as this is targeting embedded systems, I don't want to add that overhead just because the language can't do what I want.
The other thing is just declare it void
// myclass.h
class MyClass
{
...
private:
void* vendorDataUntyped;
};
and in the implememtation
//myclass.cpp
#include "vendor.h"
#define vendorData ((VendorThing*)vendorDataUntyped)
... {
vendorData->doSomething();
}
but #define's always leave a bad taste in my mouth. There must be something better.
You can avoid the additional pointer dereference by using:
#include "vendor.h"
struct VendorThingWrapper : public VendorThing {};
Of course, at that point, it makes more sense to use the name MyClassData instead of VendorThingWrapper.
MyClass.h:
struct MyClassData;
class MyClass
{
public:
MyClass();
~MyClass();
private:
MyClassData* myClassData;
};
MyClass.cpp:
struct MyClassData : public VendorThing {};
MyClass::MyClass() : myClassData(new MyClassData())
{
}
MyClass::~MyClass()
{
delete myClassData;
}
Update
I was able to compile and build the following program. The unnamed struct is not a problem.
struct MyClassData;
class MyClass
{
public:
MyClass();
~MyClass();
private:
MyClassData* myClassData;
};
typedef struct { int a; int b; } VendorThing;
struct MyClassData : public VendorThing
{
};
MyClass::MyClass() : myClassData(new MyClassData())
{
myClassData->a = 10;
myClassData->b = 20;
}
MyClass::~MyClass()
{
delete myClassData;
}
int main() {}
If you are willing to go the route of the VendorThingWrapper, then you simply allow the wrapper to contain the data itself, rather than a pointer to it. This gives you the abstraction layer and avoids the extra dereference.
// myclass.cpp
#include "vendor.h"
struct VendorThingWrapper {
VendorThing vendorData;
};
... {
vendorDataWrapper->vendorData.doSomething();
}