C++ Class wrapper around fundamental types
1) Is there any additional function calling overhead when using someClass.operator+()
No, if the function body is small and in the header, it will be inlined, and have no overhead
2) Is there a way to automatically make the compiler cast the floatWrapper to a float?
struct floatWrapper {
floatWrapper(float); //implicit conversion from float
operator float(); //implicit conversion to float.
};
Again, if the body of the function is small and in the header, it will be inlined, and have no overhead
3) Is there any additional memory overhead?
not if there's no virtual functions. A class is called polymorphic if it declares or inherits any virtual functions. If a class is not polymorphic, the objects do not need to include a pointer to a virtual function table. Moreover, performing dynamic_cast of a pointer/reference to a non-polymorphic class down the inheritance hierarchy to a pointer/reference to a derived class is not allowed, so there is no need for the objects to have some kind of type information.
4) Are there any other problems / performance impacts this could cause?
performance? No.
Also, be sure to implement binary operators that don't modify the lhs as free functions, and overload them to support all relevant permutations of floatWrapper
and float
.
struct floatWrapper {
explicit floatWrapper(float);
operator float(); //implicit conversion to float.
floatWrapper operator-=(float);
};
floatWrapper operator-(floatWrapper lhs, floatWrapper rhs)
{return lhs-=rhs;}
floatWrapper operator-(float lhs, floatWrapper rhs)
{return floatWrapper(lhs)-=rhs;}
floatWrapper operator-(floatWrapper lhs, float rhs)
{return lhs-=rhs;}
Here's my attempt at such a thing. Note you'll need a slightly different version for float/double/long double.
Wrapper Classes for Primitive Data Types
C++11 has explicit operator overloads.
struct silly_wrapper {
int foo;
explicit operator int&() { return foo; }
};
void primitive_increment(int& x) { ++x; }
int main()
{
silly_wrapper x;
primitive_increment(x); // works
x += 1; // doesn't work - can't implicitly cast
}
C++ wrapper around any collection type using templates
I started reading about template specialization to see if that'd be
any help, however I don't think this would provide a solution as the
type contained within the set would have to be known.
You can partially specialize MySack
to work with std::set
.
template <class T>
class MySack<std::set<T>> {
//...
};
However, this has the disadvantage that the partial specialization replaces the whole class definition, so you need to define all member variables and functions again.
A more flexible approach is to use policy-based design. Here, you add a template parameter that wraps the container-specific operations. You can provide a default for the most common cases, but users can provide their own policy for other cases.
template <class C, class V = typename C::value_type>
struct ContainerPolicy
{
static void push(C& container, const V& value) {
c.push_back(value);
}
static void pop(C& container) {
c.pop_back();
}
};
template <class C, class P = ContainerPolicy<C>>
class MySack
{
Collection c;
public:
typedef typename Collection::value_type value_type;
void add(const value_type& value) {
P::push(c, value);
}
};
In this case, it is easier to provide a partial template specialization for the default policy, because it contains only the functionality related to the specific container that is used. Other logic can still be captured in the MySack
class template without the need for duplicating code.
Now, you can use MySack
also with your own or third party containers that do not adhere to the STL style. You simply provide your own policy.
struct MyContainer {
void Add(int value);
//...
};
struct MyPolicy {
static void push(MyContainer& c, int value) {
c.Add(value);
}
};
MySack<MyContainer, MyPolicy> sack;
What is the meaning of a C++ Wrapper Class?
A "wrapper class" is a de facto term meaning a class that "wraps around" a resource; i.e, that manages the resource. When people write a wrapper, then, they are doing something like this:
class int_ptr_wrapper
{
public:
int_ptr_wrapper(int value = 0) :
mInt(new int(value))
{}
// note! needs copy-constructor and copy-assignment operator!
~int_ptr_wrapper()
{
delete mInt;
}
private:
int* mInt;
};
This class manages ("wraps") a pointer to an int
. All resources should be wrapped in some fashion, for cleanliness (no explicit clean up code or noise) and correctness (destructor is guaranteed to run; cannot forget to clean up, and safe with exceptions).
This pattern is called Scoped-bound Resource Management (SBRM), though a far more common (but most esoteric) name is Resource-Acquisition is Initialization (RAII). The idea is to bind a resource's clean-up to a destructor, for the reasons given above: the scope handles the rest.
Note that I said it was missing a copy-constructor and copy-assignment operator. This is due to the Rule of Three. (See linked question for detailed explanation.) The simplest way to correctly implement this rule is with the copy-and-swap idiom, explained here.
Sometimes, it's not pragmatic to write wrapper class for resource clean-up, usually when the resource is unique or used once. (Or with transactional programming.) The solution to this is called scope guard, a way of writing clean-up code inside the function that needs it.
You may find more information by searching for it in your favorite search provider (that is, Google), or going to the "primary" document here. Note that Boost provides a utility for this, as it usually does for good idioms.
How to create a C++ wrapper class for the following kind of C program?
Just create a class and put the code inside, for example in your .h
file:
class EventWrapper
{
public:
EventWrapper();
static int Event1Handler();
static void Event2Handler();
}
Then in your .cpp
file:
#include "EventWrapper.h"
// Include relevant headers for your USB device
EventWrapper::EventWrapper()
{
// Code to setup calls to Event1handler() and Event2handler()
// using Open Sound Control methods.
}
int EventWrapper::Event1Handler()
{
// Code to process event 1
}
void EventWrapper::Event2Handler()
{
// Code to process event 2
}
Without knowing all of the details of your program you may have to play around with what is static and how you want to handle it.
Related Topics
Static Polymorphism Definition and Implementation
Confusion About Pointers and References in C++
Programmatically Access CPU Fan on a Laptop? (Windows)
How to Resize a 2D Vector of Objects Given the Width and Height
How to Break Shared_Ptr Cyclic Reference Using Weak_Ptr
How to Produce Deterministic Binary Output with G++
Library Is Linked But Reference Is Undefined
How to Check If a Key Is Pressed on C++
How to Get Current CPU and Ram Usage in C++
How to Cast Simple Pointer to a Multidimensional-Array of Fixed Size
What Could C/C++ "Lose" If They Defined a Standard Abi
Allocating Vectors (Or Vectors of Vectors) Dynamically
Why Sizeof Built in Types Except Char Is Compiler Dependent in C & C++