I have multiple classes in a library that have internals that I wish to hide from client code. From the client's perspective, each class is queried from a library class and is only used as an opaque pointer. An example is as follows:
struct SomeSystem;
void doSomethingToSomeSystem(SomeSystem* system, Parameters params);
void doSomethingElseToSomeSystem(SomeSystem* system, Parameters params);
On the implementation side, SomeSystem has multiple members which are not visible to the caller. This is all fine but I don't really like the clunky usage syntax:
SomeSystem* system = lib->getSomeSystem();
doSomethingToSomeSystem(system, params);
doSomethingElseToSomeSystem(system, params);
Another approach is this:
struct SomeSystem;
namespace somesystem {
void doSomething(SomeSystem* system, Parameters params);
void doSomethingElse(SomeSystem* system, Parameters params);
}
With the usage code:
SomeSystem* system = lib->getSomeSystem();
somesystem::doSomething(system, params);
somesystem::doSomethingElse(system, params);
I could also use global methods called doSomething and doSomethingElse and depend on function overloading if another type also defines doSomething. However, in this case, it is hard to find all "members" of SomeSystem in an IDE.
I am tempted to actually use member functions:
struct SomeSystem {
void doSomething(Parameters params);
void doSomethingElse(Parameters params);
};
With the usage code:
SomeSystem* system = lib->getSomeSystem();
system->doSomething(params);
system->doSomethingElse(params);
The last snippet looks good to me but SomeSystem is no longer an opaque pointer - it actually defines members. I'm a bit wary of this. One potential problem is the one definition rule. However, the "public" definition and "private" definition of the class will only be visible to different translation units. Is there any other badness hidden here? If the client code tries to instantiate SomeSystem on the stack or using new it would obviously crash the program. But I'm willing to accept that. Perhaps I can get around this by providing a private constructor in the public interface.
Another approach is of course to define an abstract class with pure virtual methods. However, I would like to avoid the overhead of this in case it is not absolutely necessary.
EDIT:
To be clear I am wondering if it is legal to have a public header that the client includes containing a different definition of the class (with some members missing) than what the implementation uses, as the client never instantiates the class.
Public header:
struct SomeSystem {
void doSomething(Parameters params);
void doSomethingElse(Parameters params);
};
Private header:
struct SomeSystem {
Member member;
void doSomething(Parameters params);
void doSomethingElse(Parameters params);
};
Private source (includes private header):
void SomeSystem::doSomething(Parameters params) {
...
}
void SomeSystem::doSomethingElse(Parameters params) {
...
}
This works when I test it but I am unsure if it violates the standard somehow. The two headers are never included in the same translation unit.
The PIMPL idiom is probably ideal in this situation, but it is an extra indirection on every access so there is that.
An alternative if you're just after some syntactic sugar might be to take advantage of ADL - it'll at least keep the system name out of the function name:
// publicly shared header file
namespace one_system
{
struct system;
typedef system* system_handle;
void do_something(system_handle );
};
// private implementation
namespace one_system
{
struct system {};
void do_something( system_handle ) { cout << "one"; }
};
int main() {
auto handle = /* SOMETHING TO GET THIS SYSTEM */;
do_something(handle); //do_something found by ADL
return 0;
}
EDIT:
I still think PIMPL is ideal. You also don't necessarily need to have an allocation nor any additional overhead compared to what you have already.
In the case where you have a system* and a function declaration (as per your examples), the compiler already has to do an indirection. You'll need a jump to that function (as it is defined in another translation unit) and indirections to access the system within the function (since it is taken as a pointer).
All you really need to do is define an interface for the class like so:
// put this in a namespace or name it according to the system
class interface
{
system_handle m_system;
public:
interface( system_handle s ) : m_system( s ) {}
interface() = delete;
void do_something();
};
Now in another translation unit, do_something() is defined to perform it's operation on the system. The lib->GetSystem() could return an instance of the interface. The interface can be fully declared in the header file since it only consists of the public functions. The system is still entirely private (in that the user of the lib won't have the header file declaring it's contents).
Furthermore the interface can be trivially copied around by the user. It doesn't care where it's pointer comes from so the library could pass in the address of a static if it wants.
The one downside I can see to this would be that member variables would need to have accessors (and there are many who would argue that every member variable should be private and have public or protected accessors anyway).
Another would be that the *this for interface would be passed into do_something and is probably not needed. This could be solved by having do_something defined in the header file too:
void do_something() { do_something_to_system( m_system ); }
Now the compiler should be able to optimize even the *this out since do_something can be inlined and the compiler could easily just insert code to load m_system into a register and call do_something_to_system (which would be similar to what you've mentioned in your examples).
Related
If I have a header file that states
class fanStatusManager{
public:
//default constructor
fanStatusManager();
public fanstatus_t setFanStatus(fanstatus_t status);
private:
//etc
}`
and a cpp file that implements them:
fanStatusManager::fanStatusManager(){
//default constructor TODOi
}
fanstatus_t fanStatusManager::setFanStatus(fanstatus_t status){
//TODO: imlement this!
assert(false);
}
I get a bit tired of typing "fanStatusManager::" before every implementation. Is it possible to circumvent this somehow?
Although it is possible to avoid typing the name of the class if you place implementation in the header, i.e.
class fanStatusManager{
public:
public fanstatus_t setFanStatus(fanstatus_t status) {
//TODO: imlement this!
assert(false);
}
}
there is no way to work around this if you are implementing member-functions separately. This is because C++ allows free-standing functions, i.e. this syntax is perfectly valid:
fanstatus_t setFanStatus(fanstatus_t status) {
//TODO: imlement this!
assert(false);
}
The above defines a free-standing function called setFanStatus which is not associated with any class.
You can inline the member functions within the class definition
class fanStatusManager
{
public:
//default constructor
fanStatusManager()
{
//default constructor TODOi
};
fanstatus_t setFanStatus(fanstatus_t status)
{
//TODO: implement this!
assert(false);
};
private:
//etc
};
The downside of this is that, whenever you change the implementation of a member function, you are changing the header file that defines the class. That forces recompilation of EVERY compilation unit (aka source file) which depends on the header file.
In practice, unless your project is extremely SMALL and TRIVIAL (e.g. everything lives in a single source file) you are better off NOT doing this, except for very specific cases (e.g. accessors that will never be changed). The effort of typing fanStatusManager will be incurred exactly once for each member function. That is much less significant than the time and boredom you will experience as you get to watch every source file be recompiled when you change the implementation of ANY member function ..... even compilation units that don't actually use the member function you have changed.
If you don't need that class, you can just put it in namespace
namespace fanStatusManager
{
fanstatus_t setFanStatus(fanstatus_s status)
{
...
};
}
and
then you just put at the top of your file
using namespace fanStatusManager;
It won't create any object like class, but i think the functionality should be same. (If you don't need to create an object or work with any properties in that class)
What are the disadvantages of the following implementation of the pImpl idiom?
// widget.hpp
// Private implementation forward declaration
class WidgetPrivate;
// Public Interface
class Widget
{
private:
WidgetPrivate* mPrivate;
public:
Widget();
~Widget();
void SetWidth(int width);
};
// widget.cpp
#include <some_library.hpp>
// Private Implementation
class WidgetPrivate
{
private:
friend class Widget;
SomeInternalType mInternalType;
SetWidth(int width)
{
// Do something with some_library functions
}
};
// Public Interface Implementation
Widget::Widget()
{
mPrivate = new WidgetPrivate();
}
Widget::~Widget()
{
delete mPrivate;
}
void Widget::SetWidth(int width)
{
mPrivate->SetWidth(width);
}
I would prefer not to have seperate headers and sources for the private implementation part of the class because the code is essentially of the same class - should they not reside together then?
What alternatives to this version would be better?
First, let's address the question of whether the private variables should reside with the class declaration. The private part of a class declaration is part of the implementation details of that class, rather than the interface exposed by that class. Any outside "user" of that class (whether it is another class, another module, or another program in the case of an API) will care only about the public part of your class, since that is the only thing that it can use.
Putting all the private variables directly into the class in a private section might look like it puts all relevant information in the same place (in the class declaration), but it turns out that not only are private member variables not relevant information, it also creates unnecessary and unwanted dependencies between your class' clients and what amounts to be implementation details.
If, for some reason, you need to add or remove a private member variable, or if you need to change its type (e.g. from float to double), then you modified the header file which represents the public interface to your class, and any user of that class needs to be recompiled. If you were exporting that class in a library, you would also break binary compatibility since, among other things, you probably changed the size of the class (sizeof(Widget) will now return a different value). When using a pImpl, you avoid those artificial dependencies and those compatibility problems by keeping implementation details where they belong, which is out of sight of your clients.
As you have guessed, there is however a tradeoff, which might or might not be important depending on your specific situation. The first tradeoff is that the class will lose some of its const-correctness. Your compiler will let you modify the content of your private structure within a method that is declared const, whereas it would have raised an error if it would have been a private member variable.
struct TestPriv {
int a;
};
class Test {
public:
Test();
~Test();
void foobar() const;
private:
TestPriv *m_d;
int b;
};
Test::Test()
{
m_d = new TestPriv;
b = 0;
}
Test::~Test()
{
delete m_d;
}
void Test::foobar() const
{
m_d -> a = 5; // This is allowed even though the method is const
b = 6; // This will not compile (which is ok)
}
The second tradeoff is one of performance. For most applications, this will not be an issue. However, I have faced applications that would need to manipulate (create and delete) a very large number of small objects very frequently. In those rare extreme cases, the extra processing required to create an allocate an additional structure and to defer assignations will take a toll on your overall performance. Take note however that your average program certainly does not fall in that category, it is simply something that needs to be considered in some cases.
I do the same thing. It works fine for any simple application of the PImpl idiom. There is no strict rule that says that the private class has to be declared in its own header file and then defined in its own cpp file. When it is a private class (or set of functions) that is only relevant to the implementation of one particular cpp file, it makes sense to put that declaration + definition in the same cpp file. They make logical sense together.
What alternatives to this version would be better?
There is an alternative for when you need a more complex private implementation. For example, say you are using an external library which you don't want to expose in your headers (or want to make optional through conditional compilations), but that external library is complicated and requires that you write a bunch of wrapper classes or adaptors, and/or you might want to use that external library in similar way in different parts of your main project's implementation. Then, what you can do is create a separate folder for all that code. In that folder, you create headers and sources as you usually would (roughly 1 header == 1 class) and can use the external library at will (no PImpl'ing of anything). Then, the parts of your main project which need those facilities can simply include and use them only in the cpp files for implementation purposes. This is more or less the basic technique for any large wrappers (e.g., a renderer that wraps either OpenGL or Direct3D calls). In other words, it's PImpl on steroids.
In summary, if it's just for a single-serving use / wrapping of an external dependency, then the technique you showed is basically the way to go, i.e., keep it simple. But if the situation is more complicated, then you can apply the principle of PImpl (compilation firewall) but on a larger proportion (instead of a ext-lib-specific private class in a cpp file, you have a ext-lib-specific folder of source files and headers that you use only privately in the main parts of your library / project).
I think there is no big difference. You can choose more convenient alternative.
But I have some other suggestions:
Usually in PIMPL I place implementation class declaration inside interface class:
class Widget
{
private:
class WidgetPrivate;
...
};
This will prevent using of WidgetPrivate class outside of Widget class. So you dont need to declare Widget as friend of WidgetPrivate. And you can restrict access to implementation details of WidgetPrivate.
I recommend using of smart pointer. Change line:
WidgetPrivate* mPrivate;
to
std::unique_ptr<WidgetPrivate> mPrivate;
Using smart pointers you will not forget to delete member. And in case of exception thrown in constructor already created members will be always deleted.
My varian of PIMPL:
// widget.hpp
// Public Interface
class Widget
{
private:
// Private implementation forward declaration
class WidgetPrivate;
std::unique_ptr<WidgetPrivate> mPrivate;
public:
Widget();
~Widget();
void SetWidth(int width);
};
// widget.cpp
#include <some_library.hpp>
// Private Implementation
class Widget::WidgetPrivate
{
private:
SomeInternalType mInternalType;
public:
SetWidth(int width)
{
// Do something with some_library functions
}
};
// Public Interface Implementation
Widget::Widget()
{
mPrivate.reset(new WidgetPrivate());
}
Widget::~Widget()
{
}
void Widget::SetWidth(int width)
{
mPrivate->SetWidth(width);
}
I have a class parametrized with a number, but only some values are in fact valid parameters. In order to hide implementation from user and to prevent invalid instantiating, I did this:
// foo.hpp
class IClass
{
virtual void doStuff() = 0;
};
IClass& getHiddenClass(const bool& randomCondition);
// foo.cpp
template <unsigned x>
class HiddenClass : public IClass
{
public:
void doStuff()
{
/* some code using x */
}
};
IClass& getHiddenClass(const bool& randomCondition)
{
static HiddenClass<42> ifRandomCondition;
static HiddenClass<9000> ifNotRandomCondition;
if (randomCondition)
return ifRandomCondition;
else
return ifNotRandomCondition;
}
Is it OK are is there a better workaround? This example is simplified and abstract, but I also won't need to store a large number of valid instances.
Use static_assert to prevent invalid instantiation, available in C++11.
I don't understand the purpose of your "hidden class". Interfaces are meant to do exactly this - to hide the implementation from users and only let them have a predefined set of operations that they can use. Declare your interface in a separate header file and share it with user. Inherit your concrete class from the interface (in another, non-shared header file) and implement it in cpp file (again, non-shared).
That's legitimate as far as it goes. You might also try parameterizing the class by an enum instead, which you'd then case on inside the class. That might be more or less readable than what you've posted, depending on the details of your situation.
I have a class in my library which I want to expose to the users. I don't want to expose the whole class as I might want to make a binary incompatible changes later. I am confused with which of the following ways would be best.
Case 1:
struct Impl1;
struct Handle1
{
// The definition will not be inline and will be defined in a C file
// Showing here for simplicity
void interface()
{
static_cast<Impl1*>(this)->interface();
}
}
struct Impl1 : public Handle1
{
void interface(){ /* Do ***actual*** work */ }
private:
int _data; // And other private data
};
Case 2:
struct Impl2
struct Handle2
{
// Constructor/destructor to manage impl
void interface() // Will not be inline as above.
{
_impl->interface();
}
private:
Impl2* _impl;
}
struct Impl2
{
void interface(){ /* Do ***actual*** work */ }
private:
int _data; // And other private data
};
The Handle class is only for exposing functionality. They will be created and managed only inside the library. Inheritance is just for abstracting implementation details. There won't be multiple/different impl classes. In terms of performance, I think both will be identical. Is it? I am thinking of going with the Case 1 approach. Are there any issues that needs to be taken care of?
Your second approach looks very much like the compilation firewall idiom (sometimes known as the PIMPL idiom).
The only difference is that in the compilation firewall idiom, the implementation class is usually (but not always) defined as a member. Don't forget the constructor
(which allocates the Impl) and the destructor (which frees it). Along with the copy constructor and assignment operator.
The first approach also works, but it will require factory functions to create the objects. When I've used it, I've simply made all of the functions in the Handle pure virtual, and let the client code call them directly.
In this case, since client code actually has pointers to your object (in the compilation firewall idiom, the only pointers are in the Handle class itself), and the client will have to worry about memory management; if no cycles are possible, this is one case where shared_ptr makes a lot of sense. (The factory function can return a
shared_ptr, for example, and client code may never see a raw pointer.)
Inside of a static member function I need to get the type.
class MyClass
{
public:
static void myStaticFunc();
...
};
And then in the implementation I want to have:
void MyClass::myStaticFunc()
{
// Get MyClass as a type so I can cast using it
(get_type_from_static_function()*)someOtherVariable;
}
Is this even possible? Normally I would use something from typeinfo on an object but I don't have this to work with.
I do not want to just use (MyClass*) because this is going inside of a macro and I'd like to keep it as simple as possible so that it can be called without a class name.
If it helps I am using QT but I couldn't find any macros to get the current class. It doesn't necessarily need to be programmatic - it can be a macro.
Cheers!
EDIT:
Here is the actual macro function:
#define RPC_FUNCTION(funcName) \
static void rpc_##funcName(void* oOwner, RpcManager::RpcParamsContainer params){ ((__class__*)oOwner)->funcName(params); }; \
void funcName(RpcManager::RpcParamsContainer params);
I then call RPC_FUNCTION(foo) in a class declaration. I want __class__ to be whatever class declaration I am in. I'm well aware I can just add className after funcName but I want to keep this as simple as possible when actually using it. My RPC manager calls rpc_foo and passes a pointer to an object of the class I declared it in. Essentially I need to know how to determine the actual class of that void* parameter.
In Visual Studio 2012 you can use that trick, but it will not work in gcc, at least for now.
template<typename base_t>
static auto GetFunctionBaseType(void(base_t::*)())->base_t;
struct TBase
{
template<typename T> void GetBaseType();
typedef decltype(GetFunctionBaseType(&GetBaseType<void>)) this_t;
static void rpc_func1(void * ptr)
{
((this_t*)ptr)->func1();
}
};
I believe that what you're asking for at heart is simply not possible: C++ is a statically typed language, which means that all type information must be available at compile time (runtime polymorphism notwithstanding). That is, when you say,
T x;
then the type T must be known at compile time. There is no such thing as "T_from_user() x;", whereby the actual type of a variable is determined at runtime. The language just isn't designed that way.
Usually if you're asking such a question that's an indicator that you're going about a problem the wrong way, though. Typical solutions for polymorphic situations involve class inheritance and virtual functions, or other sorts of lookup tables, or really any number of different approaches. Your request for a preprocessor macro also indicates that something is off. Any programming language has its idioms, and veering too far from those is usually a bad idea.
What you want to do is called Reflection. It was implemented in .NET (I don't know, maybe in Java too) and is going to be implemented in future standards of C++.
It seems you have a few unrelated classes that have a number of methods in common (the ones that can be sent as the funcName argument in your example).
Instead of having these unrelated classes, consider a polymorphic approach. For example, let's say the functions that you support are func1 and func2, then you can work this out in this way:
class BaseClass {
public:
virtual void func1(RpcManager::RpcParamsContainer args) = 0;
virtual void func2(RpcManager::RpcParamsContainer args) = 0;
};
class MyClass1 : public BaseClass {
public:
virtual void func1(RpcManager::RpcParamsContainer args) { /* func1 implementation here */ }
virtual void func2(RpcManager::RpcParamsContainer args) { /* func2 implementation here */ }
};
class MyClass2 : public BaseClass {
public:
virtual void func1(RpcManager::RpcParamsContainer args) { /* func1 implementation here */ }
virtual void func2(RpcManager::RpcParamsContainer args) { /* func2 implementation here */ }
};
With the above design your can pass a BaseClass* around, and you can call func1 or func2 without having to do any casts, and the compiler will find the correct version to invoke. For example, in your macro you could do something like this:
#define RPC_FUNCTION(funcName) static void rpc_##funcName(BaseClass* oOwner, RpcManager::RpcParamsContainer params){ oOwner->funcName(params); };
I hope this helps!
Are searching for the function macro? It's a macro that expands to the current function name.
__FUNCTION__
No, a static method can only see static members of the class. It doesn't make sense for it to access instance members (as in, standard variables etc) as they don't exist unless the class has been instantiated.
It seems like you want something like the Singleton design pattern. This allows for only a single instance of the class to exist at a time.
Another way would be to have a static list of all instances of a class, then in the class constructor, add the this pointer to that list. As I say though, static members cannot access instance variables, as they may not exist at all.
I suppose the greater question is this: why do you need to access an instance variable from a static member? If you require access to an instance member, you should be calling the function in the context of the current instance, otherwise you're breaking the OOP paradigm pretty hard.