C++ access to a class declared and defined inside cpp file - c++

i'm working on a project with third party libraries that use some scripts where classes are
declared and defined inside .cpp files. They initialize these classes using an external constructor function that registers the instances inside an iterator to be executed on trigger events.
In this way these class seems to be not accessible from external files. But i need to use them using a not invasive method, in some way that not require to rewrite third-party code.
this is the pseudo scenario:
"Script.cpp"
#include "ScriptLoader.h"
class theirScript {
public:
theirScript() : RegisterScript("theirScript") {}
static void anUsefullStaticMethod() { ... }
}
void addTheirScript() {
new theirScript();
}
"ScriptLoader.h"
void addTheirScript();
"ScriptLoader.cpp"
#include "ScriptLoader.h"
addTheirScript();
"MyFile.cpp"
#include "ScriptLoader.h"
theirScript::anUsefullStaticMethod(); // will never work
how can i access to "theirScript" class then? is there a way where i don't have to rewrite their code?

Related

C++ Multiple Libraries Define Same Class Name

I am developing a project in which I have a vendor library, say vendor.h, for the specific Arduino-compatible board I'm using which defines class HTTPClient that conflicts with an Arduino system library, HTTPClient.h, which also defines class HTTPClient.
These two classes are unrelated other than having the same name, and the vendor implementation of an HTTP client is far less capable than the Arduino system library's implementation, so I'd prefer to use the latter. But I can't omit including the former, because I need quite a bit from the vendor.h. Essentially, I have the problem posed here, but with classes rather than functions. I have the full code of both, but given that one is a system library and the other is a vendor library, I'm reluctant to fork and edit either, as that adds lots of merging work down the road if either of them are updated, so my preference would be to find a tidy solution that doesn't edit either header.
I've tried a variety of solutions posted in other SO questions:
I do not want to leave out either header, as I need vendor.h for quite a few things and need the capabilities of HTTPClient.h's client implementation
Proper namespaces in the headers would solve the problem, I would prefer to avoid editing either header
I tried wrapping the #include <HTTPClient.h> in a namespace in my main.cpp, but that caused linking errors, as it's not a header-only library, so the header & cpp weren't in the same namespace
I tried a simple wrapper as proposed for the function in the above linked SO question in which the header contained just a forward declaration of my wrapper class & the associated cpp contained the actual class definition. This gave a compiler error of error: aggregate 'HTTP::Client client' has incomplete type and cannot be defined (Code sample of this attempt below)
main.cpp:
#include <vendor.h>
#include "httpclientwrapper.h"
HTTP::Client client;
httpclientwrapper.h:
#ifndef INC_HTTPCLIENTWRAPPER_H
#define INC_HTTPCLIENTWRAPPER_H
namespace HTTP {
class Client;
}
#endif
httpclientwrapper.cpp:
#include "httpclientwrapper.h"
#include <HTTPClient.h>
namespace HTTP {
class Client : public ::HTTPClient {};
}
In that example, I can't inherit from HTTPClient in a class definition in my header, as that will reintroduce the duplicate class name to the global namespace in my main program (hence the perhaps misguided attempt to see if a forward declaration would do the trick). I suspect that I can resolve the issue by completely duplicating the class definition of HTTPClient in my wrapper class above rather than trying to use inheritance. I would then add member definitions to my wrapper cpp which pass the call to HTTPClient's members. Before I go through the trouble of rewriting (or more likely, copy/pasting) the entire HTTPClient definition from HTTPClient.h into my own wrapper, I was wondering if there was a better or more proper way to resolve the conflict?
Thanks for you help!
As a solution was never proposed, I'm posting an answer that summarizes my research and my ultimate resolution. Mostly, I encourage the use of namespaces, because proper uses of namespaces would have eliminated the conflict. However, Arduino environments try to keep things simple to lower the barrier of entry, eschewing "complicated" features of C++, so more advanced use cases will likely continue to run into issues like this. From other SO answers and forum posts (cited where I could), here are some methods for avoiding name conflicts like this:
If you can edit the source
Edit the source code to remove the conflict or add a namespace to one of both libraries. If this is an open source library, submit a pull request. This is the cleanest solution. However, if you can't push your changes back upstream (such as when one is a system library for some hardware), you may end up with merge issues down the road when the maintainer/developer updates the libraries.
If you can't edit the source
Credit for part of this: How to avoid variable/function conflicts from two libraries in C++
For libraries that are header only libraries (or all functions are inline)
(ie, they have only a .h file without a .o or .cpp)
Include the library inside a namespace. In most code, this is frowned upon as poor form, but if you're already in a situation where you are trying to cope with a library that doesn't contain itself nicely, it's a clean and simple way to contain the code in a namespace and avoid name conflicts.
main.cpp
namespace foo {
#include library.h
}
int main() {
foo::bar(1);
}
For libraries with functions
The above method will fail to link at compile time, because the declarations in the header will be inside the namespace, but the definitions of those functions are not.
Instead, create a wrapper header and implementation file. In the header, declare your namespace and functions you wish to use, but do not import the original library. In the implementation file, import your library, and use the functions inside your new namespaced functions. That way, the one conflicting library is not imported into the same place as the other.
wrapper.h
namespace foo {
int bar(int a);
}
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
int bar(int a) {
return ::bar(a);
}
}
main.cpp
#include "wrapper.h"
int main() {
foo::bar(1);
}
You could also, for the sake of consistency, wrap both libraries so they're each in their own namespace. This method does mean that you will have to put in the effort to write a wrapper for every function you plan to use. This gets more complicated, however, when you need to use classes from the library (see below).
For libraries with classes
This is an extension of the wrapper function model from above, but you will need to put in more work, and there are a few more drawbacks. You can't write a class that inherits from the library's class, as that would require importing the original library in your wrapper header prior to defining your class, so you must write a complete wrapper class. You also cannot have a private member of your class of the type from the original class that you can delegate calls to for the same reason. The attempt at using a forward declaration I described in my question also did not work, as the header file needs a complete declaration of the class to compile. This left me the below implementation, which only works in the cases of a singleton (which was my use case anyway).
The wrapper header file should almost completely duplicate the public interface of the class you want to use.
wrapper.h
namespace foo {
Class Bar() {
public:
void f(int a);
bool g(char* b, int c, bool d);
char* h();
};
}
The wrapper implementation file then creates an instance and passes the calls along.
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
::Bar obj;
void Bar::f(int a) {
return obj.f(a);
}
bool Bar::g(char* b, int c, bool d) {
return obj.g(b, c, d);
}
char* Bar::h() {
return obj.h();
}
}
The main file will interact with only a single instance of the original class, no matter how many times your wrapper class in instantiated.
main.cpp
#include "wrapper.h"
int main() {
foo::Bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
Overall, this strikes me as a flawed solution. To fully wrap this class, I think the this could be modified to add a factory class that would be fully contained inside the wrapper implementation file. This class would instantiate the original library class every time your wrapper class is instantiated, and then track these instances. In this way, your wrapper class could keep an index to its associated instance in the factory and bypass the need to have that instance as its own private member. This seemed like a significant amount of work, and I did not attempt to do so, but would look something like the code below. (This probably needs some polish and a real look at its memory usage!)
The wrapper header file adds a constructor & private member to store an instance id
wrapper.h
namespace foo {
Class Bar() {
public:
Bar();
void f(int a);
bool g(char* b, int c, bool d);
char* h();
private:
unsigned int instance;
};
}
The wrapper implementation file then adds a factory class to manage instances of the original library's class
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
class BarFactory {
public:
static unsigned int new() {
instances[count] = new ::Bar();
return count++;
}
static ::Bar* get(unsigned int i) {
return instances[i];
}
private:
BarFactory();
::Bar* instances[MAX_COUNT]
int count;
};
void Bar::Bar() {
instance = BarFactory.new();
}
void Bar::f(int a) {
return BarFactory.get(i)->f(a);
}
bool Bar::g(char* b, int c, bool d) {
return BarFactory.get(i)->g(b, c, d);
}
char* Bar::h() {
return BarFactory.get(i)->h();
}
}
The main file remains unchanged
main.cpp
#include "wrapper.h"
int main() {
foo::bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
If all of this seems like a lot of work, then you're thinking the same thing I did. I implemented the basic class wrapper, and realized it wasn't going to work for my use case. And given the hardware limitations of the Arduino, I ultimately decided that rather than add more code to be able to use the HTTPClient implementation in either library, I wrote my own HTTP implementation library in the end, and so used none of the above and saved several hundred kilobytes of memory. But I wanted to share here in case somebody else was looking to answer the same question!

C++ dynamic library with public api that obscures dependent libraries

I am trying to create a multi-platform library in C++ for use by C++ consumer applications. Call my library A. I want to ship a dynamic library file per target platform, and a header file (call this export.h) that the consumer app could use to compile and execute. My library depends on a third-party open-source library, written in c, which is difficult to link to correctly; call this library B.
In order to save my consumers the pains of linking to B, I want to abstract every call to it so that the consumer need not even have a single header file from B. Consumer app (C) should be able to compile with only A.dll, B.dll and export.h; and run with only A.dll and B.dll as dependencies (substituting the platform-specific suffix for a shared library as needed).
B defines a great many types, mostly structs. (B is not written in objective c, although it probably should have been.) Part of A's job is to produce classes that contain and manage groups of structs around logical lines, which are readily apparent. C needs to call functions belonging to classes in A, so the function prototypes need to be in export.h, but the B types cannot be in export.h or else C will need to include headers from B.
Is there a syntax that lets me define the public members of a class (in A) without also defining all the private members?
Obviously, there are no public members in A that rely on types from B. The closest thing I've found so far is this question. Opaque pointers may be part of the solution, but C needs access to functions of classes in A. I really don't want to write a helper function for every public A class member, though that would probably work. Any ideas?
Edit: As requested, explanation code.
Worker.h:
#include <SomeThirdPartyLib.h>
class Worker {
public:
Worker();
~Worker();
void DoWork();
private:
Truck t;
}
SomeThirdPartyLib.h:
typedef struct TruckS {
char data[200];
char* location;
} Truck;
Worker.cpp:
#include "worker.h"
Worker::Worker() {}
Worker::~Worker() {}
Worker::DoWork() {
t.location = "Work";
}
main.cpp:
#include <export.h>
int main(int argc, char** argv) {
Worker w();
w.DoWork();
}
Now I'm looking for the syntax to put in export.h that would allow this external application to be compiled using that header and my dll, but without requiring access to SomeThirdPartyLib.h.
Here is a technique that may be close to what you want to achieve.
You can define an interface that relies only on public interfaces from A, and therefore lacks any dependency on B. The interface class includes a factory. This interface would be part of the header file for your library.
class Interface {
public:
virtual void foo () = 0;
virtual void bar () = 0;
static std::unique_ptr<Interface> make ();
virtual ~Interface () = default;
};
In a source file of your library, you would include header files for both A and B, and create an implementation of the interface as well as a definition of the factory.
class Implementation : public Interface {
//...
};
std::unique_ptr<Interface>
Interface::make () {
return std::make_unique<Implementation>();
}
So, users of your library get access to the interface, and can call the public methods without any knowledge of private members or private methods.
Try it online!

C++ Goodpractice for multiple derived class of the same base class

Goal: I am making a program which has 10 pattern styles, which are implemented as different classes that derive from a common pattern base class.
The main.cpp creates a pattern style depending on the style chosen by the user.
The question:
how can main know about all pattern styles without creating so many headers?
ex : these will be the files if separated.
baseclass.h
baseclass.cpp
derivedclass1.h
derivedclass1.cpp
derivedclass2.h
derivedclass2.cpp
derivedclass3.h
derivedclass3.cpp
derivedclass4.h
derivedclass4.cpp
main.cpp
inside main.cpp:
#include "derivedclass1.h"
#include "derivedclass2.h"
#include "derivedclass3.h"
#include "derivedclass4.h"
Isn't this too much?
Is there a way to just call 1 namespace which has a list of of all derived class like unity (deriving in monobehavior)? i know it uses c# but still..
=====thoughts=====
Maybe a foreach loop that calls all derived class of the same base class? or should I make a main_header.h which #include all the style and include that from main.cpp?
Include header files, not .cpp files.
If you still need to include .cpp files for some reason: Don't (but rename it to _impl.h etc. for templates)
Instead include header files
#include "derivedclass1.h"
#include "derivedclass2.h"
#include "derivedclass3.h"
#include "derivedclass4.h"
If that seems too much: it is not a sin to put alike classes in the same file (albeit it should be a rare case):
Then include that:
#include "allderivedclasses.h"
Your main concern seems to be "how can main know about all pattern styles?".
The answer is a factory function takes a pattern style name (and maybe some arguments) and produces the correct pattern style object. Each pattern style implementation is responsible for registering itself to the factory, such that main can remain oblivious.
For a more elaborate explanation of this technique, see https://dev.to/fenbf/factory-with-self-registering-types--35h1
In the code below, the PatternStyle class exposes two static functions:
register_pattern: Each sub-class can register its name and a static constructor function at startup time into a std::map pattern_styles.
create: Looks up the name in the std::map and invokes the constructor, if any.
pattern_style.h
class PatternStyle {
...
public:
using Constructor = std::function<std::unique_ptr<PatternStyle>()>;
static std::unique_ptr<PatternStyle> create(const std::string& name);
static bool register_pattern(const std::string& name, Constructor ctor);
};
pattern_style.cpp
static std::map<std::string, PatternStyle::Constructor> pattern_styles;
std::unique_ptr<PatternStyle> PatternStyle::create(const std::string& name) {
auto it = pattern_styles.find(name);
if (it == pattern_styles.cend())
return {};
else
return it->second();
}
bool PatternStyle::register_pattern(const std::string& name, Constructor ctor) {
pattern_styles[name] = ctor;
return true;
}
This allows a subclass to register itself like so:
wavy_pattern_style.h
class WavyPatternStyle : public PatternStyle {};
wavy_pattern_style.cpp
static bool registration = PatternStyle::register_pattern("wavy", std::make_unique<WavyPatternStyle>);
Note: this use of make_unique requires C++14. If you only have C++11, you will need to make a dedicated constructor function (or use a lambda).
With this construct, it is a simple matter of defining pattern styles in separate files and including them in your build system, which solves your secondary concern.

Interfaces, hiding concrete implementation details in C++

I have a question regarding hidinging interface details in C++ libraries. The problem is ilustrated with the following example:
Let's say w have a class called ISystem which exposes methods like Init, Run, Tick, Shutdown, GetXXXSubSystem.
Where X are pointers various interfaces like: ISoundSystem, IInputSystem
We also have concrete implementations of ISystem like:
Win32System, OSXSystem etc.
These specific implementations use a pimpl idiom to hide internals
and for example Win32System instantiates Win32RawInputSystem
as input system manager.
All such managers do have their own Init, Run, Tick and Shutdown methods
which are not part of the interface (only concrete implementation) and these are run and managed by the concrete system implementation.
The user calling GetXXXSubSystem gets interface pointer without those methods (Init etc..) but
still he could cast the pointer he gets to concrete implementation
and trigger methods like Init Run Tick etc. which he shouldn't have access to.
The question is, is it possible to hide the concrete class somehow? I tried to make those methods
protected in the concrete implementations and template the class on type which would eventually be friend but this appears to be prohobited and existing hacks do not work with VC11.
The only way I can think of right know is to transfer the concrete implementation declaration from header
into the cpp file of Win32System class but I see ahuge drawback of doing this (even not sure if this would work), because this way each subsystem
would have to be also part of this cpp file and it would become a maintainability nightmare.
Another solution I am thinking about is using factory method like
(RawInput.h)
IInputSystem* CreateRawInputSystem();
(RawInput.cpp)
class RawInput : public IInputSystem {}; ...
and move definition of the class to cpp file but then, how I would acces this type from other parts of my library (ie in Win32System impl)?
Is it possible to include .cpp files form other .cpp files?
Thanks in advance for any tips.
If you're developing a library here, then you can simply choose not to export the header files of the concrete classes that you do not want to expose. You cannot cast to a class of which you do not have a definition.
Example :
MyProjectFolder/Src/Export/ISystem.h
#ifndef ISYSTEM_H
#define ISYSTEM_H
#include "IInputSystem.h"
class ISystem
{
public:
virtual ~ISystem() {};
virtual void Run()=0;
virtual IInputSystem* GetInputSystem()=0;
};
#endif
MyProjectFolder/Src/Export/IInputSystem.h
#ifndef IINPUTSYSTEM_H
#define IINPUTSYSTEM_H
class IInputSystem
{
public:
virtual ~IInputSystem() {};
virtual void Foo()=0;
virtual void Bar()=0;
};
#endif
MyProjectFolder/Src/Export/Win32System.h
#ifndef WIN32SYSTEM_H
#define WIN32SYSTEM_H
#include "ISystem.h"
class Win32System : public ISystem
{
public:
Win32System();
virtual void Run();
virtual IInputSystem* GetInputSystem();
private:
struct impl;
impl* m_pImpl;
};
#endif
MyProjectFolder/Src/Win32RawInputSystem.h
#ifndef WIN32RAWINPUTSYSTEM_H
#define WIN32RAWINPUTSYSTEM_H
#include "IInputSystem.h"
class Win32RawInputSystem : public IInputSystem
{
public:
virtual void Foo();
virtual void Bar();
virtual void Run(); // you do not want to expose that function
};
#endif
MyProjectFolder/Src/Win32System.cpp
#include "Win32System.h"
#include "Win32RawInputSystem.h"
struct Win32System::impl
{
Win32RawInputSystem inputSys;
};
Win32System::Win32System()
: m_pImpl(new impl)
{
}
void Win32System::Run()
{ // run run run
}
IInputSystem* Win32System::GetInputSystem()
{
return &m_pImpl->inputSys;
}
So when building your project its include search path is not only Src/ but also Src/Export/. From within your library project you can use all classes, including Win32RawInputSystem. When deploying your library you only give away those headers that reside in the Src/Export/ folder. Clients can still use the library, but they can never cast IInputSystem* to Win32RawInputSystem* because they do not have that header. Therefore the users of that library can invoke Foo() and Bar() on the IInputSystem*, but they'll never be able to invoke Run().

How should I separate functions, class definitions and main code within a project?

I currently have a project with 3 files.
One DBheader.h header file that includes:
Class declarations (with their smaller member function definitions)
A DBdefinitions.cpp file with:
Larger member function definitions for the classes in DBheader.h
and finally a DBmain.cpp file that contains:
Main code
Some large (non-memeber) functions that use the classes defined in DBheader.h
I would preferably like to move these functions somewhere to make my DBmain.cpp file less cluttered. Should/could I move them to the DBdefinition.cpp file or do I need to create a new separate .cpp file for non-member functions?
Here's a rough of what my code looks like if the above is unclear.
//DBheader.h
//libraries..
class course{
//member data..
void printinfo();
}
-
//DBdefinitions.cpp
#include "DBheader.h"
void course::printinfo(){/*do stuff*/}
-
//DBmain.cpp
#include "DBheader.h"
typedef map<int,course> record;
void fileinput(record &map);
int main(){
//stuff
}
void fileinput(record &map){
//lots of code
}
You should organize free functions that are part of the public interface in a similar fashion you used for the class definition: a header with the declaration and an implementation file with the implementations.
If they are particular to a specific translation unit, keep them in that implementation file.
All free functions should be declared inside a namespace (named for the public ones, anonymous for "private" free functions).