Encapsulation (information hiding) is a very useful concept, ensuring that only the barest minimal details are published in the API of a class.
But I can't help thinking that the way C++ does this is a little deficient. Take, for example, a (Celsius-based) temperature class like:
class tTemp {
private:
double temp;
double tempF (double);
public:
tTemp ();
~tTemp ();
setTemp (double);
double getTemp ();
double getTempF ();
};
Now, that's a very simple case but it illustrates a point that the encapsulation isn't perfect. "Real" encapsulation would hide all unnecessary information such as:
the fact that the data is maintained internally in the temp variable (and its type).
the fact that there is an internal routine for Fahrenheit/Celsius conversion.
So, ideally, it seems to me that the implementor of the class would use the above header but any client of the class would see just the public bits.
Don't get me wrong, I'm not criticising C++ since it meets the stated purpose of preventing clients from using the private bits but, for more complex classes, you could easily work out internal details based on the names, types and signatures of private data and functions.
How does C++ allow implementors to hide this information (assuming it is possible)? In C, I'd simply use an opaque type so that the internal details would be hidden but how would you do that in C++?
I suppose I could maintain an separate class, totally hidden from the client and known only to my own code, and then keep an instance of it with a void * in the visible class (casting within my code), but that seems a rather painful process. Is there an easier way in C++ to achieve the same end?
C++ uses an idiom known as "pimpl" (private implementation / pointer to implementation) to hide implementation details. Take a look at this MSDN article for details.
In short, you expose your interface in a header file as normal. Let's use your code as an example:
tTemp.h
class tTemp {
private:
class ttemp_impl; // forward declare the implementation class
std::unique_ptr<ttemp_impl> pimpl;
public:
tTemp ();
~tTemp ();
setTemp (double);
double getTemp (void);
double getTempF (void);
};
The public interface remains, but the private internals have been replaced with a smart pointer to a private implementation class. This implementation class is located only in the header's corresponding .cpp file, it is not exposed publicly.
tTemp.cpp
class tTemp::ttemp_impl
{
// put your implementation details here
}
// use the pimpl as necessary from the public interface
// be sure to initialize the pimpl!
tTtemp::tTemp() : pimpl(new ttemp_impl) {}
This also has the added advantage of allowing you to change the internals of your class without changing the header, which means less recompiling for users of your class.
For a full solution as shown in paxdiablo's pre-C++11 answer, but with unique_ptr instead of void *, you can use the following. First ttemp.h:
#include <memory>
class tTemp {
public:
tTemp();
~tTemp();
void setTemp(double);
double getTemp (void);
double getTempF (void);
private:
class impl;
std::unique_ptr<impl> pimpl;
};
Next, the "hidden" implementation in ttemp.cpp:
#include "ttemp.h"
struct tTemp::impl {
double temp;
impl() { temp = 0; };
double tempF (void) { return temp * 9 / 5 + 32; };
};
tTemp::tTemp() : pimpl (new tTemp::impl()) {};
tTemp::~tTemp() {}
void tTemp::setTemp (double t) { pimpl->temp = t; }
double tTemp::getTemp (void) { return pimpl->temp; }
double tTemp::getTempF (void) { return pimpl->tempF(); }
And, finally, ttemp_test.cpp:
#include <iostream>
#include <cstdlib>
#include "ttemp.h"
int main (void) {
tTemp t;
std::cout << t.getTemp() << "C is " << t.getTempF() << "F\n";
return 0;
}
And, like paxdiablo's solution, the output is:
0C is 32F
with the added advantage of more type safety. This answer is the ideal solution for C++11, see paxdiablo's answer if your compiler is pre-C++11.
Thought I would flesh out the "interface class / factory" technique that Don Wakefield mentions in his comment. To start with, we abstract away all implementation detail from the interface and define an abstract class that contains only the interface to a Temp:
// in interface.h:
class Temp {
public:
virtual ~Temp() {}
virtual void setTemp(double) = 0;
virtual double getTemp() const = 0;
virtual double getTempF() const = 0;
static std::unique_ptr<Temp> factory();
};
Clients that want a Temp object call the factory to build one. The factory could provide some complicated infrastructure that returns different implementations of the interface in different conditions, or something as simple as the "just give me a Temp" factory in this example.
It's possible for implementation classes to implement the interface by providing overrides for all of the pure virtual function declarations:
// in implementation.cpp:
class ConcreteTemp : public Temp {
private:
double temp;
static double tempF(double t) { return t * (9.0 / 5) + 32; }
public:
ConcreteTemp() : temp() {}
void setTemp(double t) { temp = t; }
double getTemp() const { return temp; }
double getTempF() const { return tempF(temp); }
};
and somewhere (possibly in the same implementation.cpp) we need to define the factory:
std::unique_ptr<Temp> Temp::factory() {
return std::unique_ptr<Temp>(new ConcreteTemp);
}
This approach is a little more easily extensible than pimpl: anyone who wants to can implement the Temp interface instead of there being only one "secret" implementation. There's also a bit less boilerplate since it's using the language's builtin mechanisms for virtual dispatch to dispatch interface function calls to implementations.
There is a non-orthodox approach I've seen used by pugi::xml_document from the pugixml library, and it doesn't have the overheads of pimpl or abstract classes. It goes like this:
You reserve a char array in your publicly exposed class:
class tTemp {
public:
tTemp();
~tTemp();
void setTemp(double);
double getTemp();
double getTempF();
alignas(8) char _[8]; // reserved for private use.
};
Note that
the alignment and size in this example are hardcoded. For a real application you would use an expression to estimate that based on the size of the machine word, for example sizeof(void*)*8 or similar.
adding private won't provide any additional protection because any access to _ can just as well be replaced with a cast to char*. It's the lack of implementation details in the header that provides the encapsulation.
Next, in the translation unit, you can implement tTemp as follows:
struct tTempImpl {
double temp;
};
static_assert(sizeof(tTempImpl) <= sizeof(tTemp::_), "reserved memory is too small");
static double tempF(tTemp &that) {
tTempImpl *p = (tTempImpl*)&that._[0];
return p->temp * 9 / 5 + 32;
}
tTemp::tTemp() {
tTempImpl *p = new(_) tTempImpl();
}
tTemp::~tTemp() {
((tTempImpl*)_)->~tTempImpl();
}
tTemp::tTemp(const tTemp& orig) {
new(_) tTempImpl(*(const tTempImpl*)orig._);
}
void tTemp::setTemp(double t) {
tTempImpl *p = (tTempImpl*)_;
p->temp = t;
}
double tTemp::getTemp() {
tTempImpl *p = (tTempImpl*)_;
return p->temp;
}
double tTemp::getTempF() {
return tempF(*this);
}
This is, surely, more verbose compared to other presented approaches. But this is the only zero-overhead approach I know that can truly hide all compile-time dependencies from the headers. Note that it also provides a degree of ABI stability -- you can change tTempImpl as long as its size does not exceed the reserved memory.
For a more detailed discussion about encapsulation in C++ see my True encapsulation in C++ blog post.
Private implementation (PIMPL) is the way in which C++ can provide this feature. Since I had trouble getting the unique_ptr variation to compile with CygWin g++ 4.3.4, another way to do it is to use a void * within your visible class as follows. This will allow you to use pre-C++11 compilers, and compilers like the aforementioned gcc which only had experimental support for C++11.
First, the header file ttemp.h, the one the client includes. This declares opaquely the internal implementation structure so that those internals are fully hidden. You can see that the only detail revealed is the name of the internal class and variable, neither of which need to reveal any information on how the internals work:
struct tTempImpl;
class tTemp {
public:
tTemp();
~tTemp();
tTemp (const tTemp&);
void setTemp(double);
double getTemp (void);
double getTempF (void);
private:
tTempImpl *pimpl;
};
Next, the implementation file ttemp.cpp which both declares and defines the opaque stuff, and also defines the user-visible details. Since the user never sees this code, they do not know about how it's implemented:
#include "ttemp.h"
struct tTempImpl {
double temp;
tTempImpl() { temp = 0; };
double tempF (void) { return temp * 9 / 5 + 32; };
};
tTemp::tTemp() : pimpl (new tTempImpl()) {
};
tTemp::~tTemp() {
delete pimpl;
}
tTemp::tTemp (const tTemp& orig) {
pimpl = new tTempImpl;
pimpl->temp = orig.pimpl->temp;
}
void tTemp::setTemp (double t) {
pimpl->temp = t;
}
double tTemp::getTemp (void) {
return pimpl->temp;
}
double tTemp::getTempF (void) {
return pimpl->tempF();
}
Note that the internal implementation details are not protected in any way from the visible class itself. You could define the internals as a class with accessors and mutators but it seems unnecessary since it should be tightly coupled in this case.
One word of note from above: because you're using a pointer to control the hidden aspects, the default shallow copy constructor would cause grief by having two visible objects referring to the same private member (leading to a double-delete in the destructor). So you need to (as I have) provide a deep-copy copy constructor to prevent this.
Lastly, a test program showing how the whole thing hangs together:
#include <iostream>
#include "ttemp.h"
int main (void) {
tTemp t;
std::cout << t.getTemp() << "C is " << t.getTempF() << "F\n";
return 0;
}
The output of that code being, of course:
0C is 32F
Related
I am trying to optimize the run time of my code and I was told that removing unnecessary virtual functions was the way to go. With that in mind I would still like to use inheritance to avoid unnecessary code bloat. I thought that if I simply redefined the functions I wanted and initialized different variable values I could get by with just downcasting to my derived class whenever I needed derived class specific behavior.
So I need a variable that identifies the type of class that I am dealing with so I can use a switch statement to downcast properly. I am using the following code to test this approach:
Classes.h
#pragma once
class A {
public:
int type;
static const int GetType() { return 0; }
A() : type(0) {}
};
class B : public A {
public:
int type;
static const int GetType() { return 1; }
B() : {type = 1}
};
Main.cpp
#include "Classes.h"
#include <iostream>
using std::cout;
using std::endl;
using std::getchar;
int main() {
A *a = new B();
cout << a->GetType() << endl;
cout << a->type;
getchar();
return 0;
}
I get the output expected: 0 1
Question 1: Is there a better way to store type so that I do not need to waste memory for each instance of the object created (like the static keyword would allow)?
Question 2: Would it be more effective to put the switch statement in the function to decide that it should do based on the type value, or switch statement -> downcast then use a derived class specific function.
Question 3: Is there a better way to handle this that I am entirely overlooking that does not use virtual functions? For Example, should I just create an entirely new class that has many of the same variables
Question 1: Is there a better way to store type so that I do not need to waste memory for each instance of the object created (like the static keyword would allow)?
There's the typeid() already enabled with RTTI, there's no need you implement that yourself in an error prone and unreliable way.
Question 2: Would it be more effective to put the switch statement in the function to decide that it should do based on the type value, or switch statement -> downcast then use a derived class specific function.
Certainly no! That's a heavy indicator of bad (sic!) class inheritance hierarchy design.
Question 3: Is there a better way to handle this that I am entirely overlooking that does not use virtual functions? For Example, should I just create an entirely new class that has many of the same variables
The typical way to realize polymorphism without usage of virtual functions is the CRTP (aka Static Polymorphism).
That's a widely used technique to avoid the overhead of virtual function tables when you don't really need them, and just want to adapt your specific needs (e.g. with small targets, where low memory overhead is crucial).
Given your example1, that would be something like this:
template<class Derived>
class A {
protected:
int InternalGetType() { return 0; }
public:
int GetType() { static_cast<Derived*>(this)->InternalGetType(); }
};
class B : public A<B> {
friend class A<B>;
protected:
int InternalGetType() { return 1; }
};
All binding will be done at compile time, and there's zero runtime overhead.
Also binding is safely guaranteed using the static_cast, that will throw compiler errors, if B doesn't actually inherits A<B>.
Note (almost disclaimer):
Don't use that pattern as a golden hammer! It has it's drawbacks also:
It's harder to provide abstract interfaces, and without prior type trait checks or concepts, you'll confuse your clients with hard to read compiler error messages at template instantiantion.
That's not applicable for plugin like architecture models, where you really want to have late binding, and modules loaded at runtime.
If you don't have really heavy restrictions regarding executable's code size and performance, it's not worth doing the extra work necessary. For most systems you can simply neglect the dispatch overhead done with virtual function defintions.
1)The semantics of GetType() isn't necessarily the best one, but well ...
Go ahead and use virtual functions, but make sure each of those functions is doing enough work that the overhead of an indirect call is insignificant. That shouldn't be very hard to do, a virtual call is pretty fast - it wouldn't be part of C++ if it wasn't.
Doing your own pointer casting is likely to be even slower, unless you can use that pointer a significant number of times.
To make this a little more concrete, here's some code:
class A {
public:
int type;
int buffer[1000000];
A() : type(0) {}
virtual void VirtualIncrease(int n) { buffer[n] += 1; }
void NonVirtualIncrease(int n) { buffer[n] += 1; }
virtual void IncreaseAll() { for i=0; i<1000000; ++i) buffer[i] += 1; }
};
class B : public A {
public:
B() : {type = 1}
virtual void VirtualIncrease(int n) { buffer[n] += 2; }
void NonVirtualIncrease(int n) { buffer[n] += 2; }
virtual void IncreaseAll() { for i=0; i<1000000; ++i) buffer[i] += 2; }
};
int main() {
A *a = new B();
// easy way with virtual
for (int i = 0; i < 1000000; ++i)
a->VirtualIncrease(i);
// hard way with switch
for (int i = 0; i < 1000000; ++i) {
switch(a->type) {
case 0:
a->NonVirtualIncrease(i);
break;
case 1:
static_cast<B*>(a)->NonVirtualIncrease(i);
break;
}
}
// fast way
a->IncreaseAll();
getchar();
return 0;
}
The code that switches using a type code is not only much harder to read, it's probably slower as well. Doing more work inside a virtual function ends up being both cleanest and fastest.
I am working with a large code base, and there are a number of publicly defined variables. Unfortunately, the functions of accessing these variables has changed, and this new functionality would be best encapsulated by public accessors and a private instance variable.
So, I am trying to make this change. To do so, I planned to make each public property private and then create accessors. But, I don't want to change any of the code which accesses the old public properties. For example:
After changing the public property to private, I have the following class:
class Test {
private:
int item = 5;
public:
int GetItem() {
return item;
};
void SetItem(int new_item) {
item = new_item;
};
};
In the past, "item" used to be a public property of the class, and it was accessed through:
Test* t = new Test();
int item = t->item;
Now though, I need to add new functionality to the way in which "item" is retrieved. For example:
int GetItem() {
// Some complicated code which changes "item"
return item;
};
How can I keep the same syntax:
int item = t->item;
But have this actually perform:
int item = t->GetItem();
Any help is greatly appreciated!
You can make int item = t.item; work, by defining item as a member variable whose type is a helper class with a custom conversion operator int() defined. Also, operator=(int new_value) to intercept the set operation.
What you can't make work is
int& item = t.item;
or
int* pitem = &t.item;
because both of these enable direct memory access, without going through any getter or setter. When creating the reference or pointer, you can't even determine how many accesses there will be or whether they will be reads or writes.
C++ is a compiled non-reflective language, i.e. you can't just "look names up as you access an element", because in the binary, there are no names anymore.
So, no, what you want is impossible. (at least not without restrictions – see Ben Voigt's excellent answer; having a "transparent" property which is in fact a getter call surely isn't worth the pitfalls you're building with that-)
Also, please don't let your C++ become Java just for the sake of having getters and setters – if they don't actually add security, I don't really see the point of using them
In case that your question is based in the fact that you don't want to call 2 different functions for setting and getting, you can make a function that returns a reference of the member:
int& Item()
{
// Some complicated code which changes *items
return item;
}
as you can see, the return type is int& instead of int. so you can use this function this way
t.Item() = someValue;
To expand on Ben Voight's answer, you can define a proxy template that allows this without the boiler plate:
template <typename Return, typename Containing, Return (Containing::* func)()>
struct proxy
{
Containing& c;
proxy(Containing& c) : c(c) {}
operator Return() { return (c.*func)(); }
Return& operator=(const Return& r) { return (c.*set)() = r; }
};
Then to define a "property"
class c {
int y_;
int get_y() { std::cout << "Getting y" << std::endl; return y_; }
public:
proxy<int, x, &x::get_y> y;
c() : y(*this) {}
};
And in client code
int main() {
c val;
val.y = 5;
std::cout << val.y << std::endl;
}
As the question asks...
What is the difference between:
class MyClass
{
public:
MyClass(){
m_a = 0;
}
private:
int m_a;
friend void set_a(MyClass &a);
};
void set_a(MyClass &a)
{
std::cout << a.m_a << std::endl;
a.m_a = 500;
std::cout << a.m_a << std::endl;
}
int main(void) {
MyClass my_class_instance;
set_a(my_class_instance);
system("pause");
}
and:
class MyClass
{
public:
MyClass(){
m_a = 0;
}
void set_a(){
std::cout << this->m_a << std::endl;
this->m_a = 500;
std::cout << this->m_a << std::endl;
}
private:
int m_a;
};
int main(void) {
MyClass my_class_instance;
my_class_instance.set_a();
system("pause");
}
Is it simply the preferred structure of the function, or are there real, measurable differences? From what I can tell, both functions achieve the same results in all circumstances, except if you had multiple overloads for the first example, that took different types of objects.
As the C++ FAQ says: Use a member when you can, and a friend when you have to.
There are situations where making friend a free function is preferable, most situations related to the fact that the first parameter of a member function is always of that class (Its the hidden *this parameter).
One example is arithmetic operators overloading:
Suppose you write a complex class which represents complex numbers. Using a member operator+() you could write expressions like complex + float, but not float + complex. But you could do it with the free form of the operator+:
class complex
{
...
friend complex operator+( float f , complex c );
};
This whole question comes down to "Why would I use friends in C++?". The answer is that when used properly, friends enhance encapsulation. This is an FAQ:
Do friends violate encapsulation?
Your example is too short and too abstract, of course. Some better, real life examples I could think of from the top of my head involve iterators. You may have many iterator objects referring to only one container object, and you may want the iterator to be able to access private member variables of the container. At the same time, you don't want the container to expose those variables to the rest of the world.
Such a design could be perfectly implemented with the friend feature.
Many people defend that making accessor methods, you can in a later stage of development put barriers to the incorrect access to the member variables (or even change the member variables totally) without breaking your (correct) clients.
One classical case is of a
class ComplexNumber {
double real, imaginary;
public:
double re() { return re; }
double setRe(double v) { return re = v; }
// and so on ...
};
one day you discover, in some maintenance, that you need the polar coordinates for that number, so you add the methods
double rho() { /* calculate rho */ }
double theta() { /* calculate theta */ }
double setRho(double v) { /* calculate real, imaginary, based on the new rho */ }
and so on.
Later yet, you discover that the users of the class use far more often polar than Cartesian coordinates for complex numbers, and that the conversions have been the bottleneck of a performance problem, so you ditch real and imaginary and store rho and theta, and change the getter and setter methods for the new -- more efficient -- storage for rho, theta, re, im, and so on. All the clients of your class will recompile without problems, because you changed your implementation but kept your interfaces stable.
I'm trying to compare objects of a common base class together. The comparison should fail (output a failure string, for instance) in any case when the two objects differ in class, or differ in values specific to the object. Ideally the comparison is somehow enforced, such that a new derived class would also have to write a comparison function to members of its class. Here's a code example:
#include <iostream>
#include <string>
#include <vector>
class Vehicle
{
public:
virtual std::string compareTo(Vehicle* v) = 0;
};
class Bicycle : public Vehicle
{
public:
Bicycle() { color_ = "red"; }
std::string compareTo(Vehicle* v) { return "We're different vehicles."; }
std::string compareTo(Bicycle* b) { return color_.compare(b->color_) ? "We're different bicycles." : "We're the same bicycle."; }
private:
std::string color_;
};
class Car : public Vehicle
{
public:
Car() { style_ = "sedan"; }
std::string compareTo(Vehicle* v) { return "We're different vehicles."; }
std::string compareTo(Car* c) { return style_.compare(c->style_) ? "We're different cars." : "We're the same car."; }
private:
std::string style_;
};
int main()
{
Vehicle* compareFrom = new Bicycle();
std::vector<Vehicle*> compareTos;
compareTos.push_back(new Bicycle());
compareTos.push_back(new Car());
std::vector<Vehicle*>::iterator it;
for (it = compareTos.begin(); it != compareTos.end(); ++it)
std::cout << compareFrom->compareTo(*it) << std::endl;
return 0;
}
Currently, the output (which you can see here) says "We're different vehicles". I know this is happening because I'm using the abstract base pointer. The problem is how to fix it!
The output I'd like to have is that the bicycles output that they're the same, because they do have the same color. Bicycles and cars should output that they're different vehicles. Bicycles of different colors and cars of different styles should also output that they're different. I feel like there must be a great pattern to use to solve this problem, but I'm getting mired in dynamic casting or unsafe downcast issues. Also, I would like for the comparison function to be enforced among members of the same class (so Bicycles must be able to compare to other Bicycles).
You want Multiple Dispatch (i.e. select which function to call dynamically based on more than one variable, not just 'this'). This is because you need to inspect the type somehow, otherwise the compiler will do a static analysis on the types and select what function to call (The virtual one in Vehicle).
No way around that. dynamic_cast is your friend here, but you may want to roll your own RTTI system for performance (or other) reasons. (The wikipedia article shows one way..)
std::string Bicycle::compareTo(Vehicle* v) {
if (Bicycle* b = dynamic_cast<Bicycle*>(v)) {
return compareTo(b);
} else {
return "We're different vehicles.";
}
}
There is an implementation of this pattern in the Loki C++ library which might help if you have many types that need comparing.
Multiple dispatch is not supported by the language in C++, nor in most mainstream languages. There was a proposal to add it to C++11 though, see this question and Bjarne's paper. I think it was rejected because (known and unknown) issues with dynamic linking, which the C++ standard sadly knows nothing about.
Your code has the big problem that it’s not easily extensible (violates the open/closed principle). You can however delegate the comparison to a base class method.
Also, if you want to enforce the semantic (a good thing) then you will not be able to circumvent downcasting, sorry.
To make it robust and extensible,
Make the base method pure virtual
Provide an implementation for the base method (yes, this works! Even if it’s pure virtual) that compares the objects’ types
In the derived classes, use the base class’ implementation to test for type equality, then do the actual logic check.
#include <iostream>
#include <iomanip>
#include <string>
#include <typeinfo>
struct vehicle {
virtual bool compare_to(vehicle const& other) const = 0;
};
bool vehicle::compare_to(vehicle const& other) const {
return typeid(*this) == typeid(other);
}
struct car : vehicle {
std::string color;
car(std::string const& color) : color(color) { }
bool compare_to(vehicle const& other) const {
bool result = vehicle::compare_to(other);
return result and (color == static_cast<car const&>(other).color);
}
};
struct bike : vehicle {
int spokes;
bike(int spokes) : spokes(spokes) { }
bool compare_to(vehicle const& other) const {
bool result = vehicle::compare_to(other);
return result and (spokes == static_cast<bike const&>(other).spokes);
}
};
int main() {
car c1("blue");
car c2("red");
bike b1(42);
std::cout << std::boolalpha;
std::cout << c1.compare_to(c2) << "\n"
<< c1.compare_to(b1) << "\n"
<< c1.compare_to(c1) << "\n";
}
The above code, the static_cast is safe since we have ensured beforehand that the type is the same, thus the cast will never fail.
Note that the use of typeid here is entirely legitimate. It shouldn’t even be very inefficient since there is no deep type hierarchy to walk. But if you want to make this more efficient you can implement a simple own mechanism which uses a static table in the base class to map each created instance to type-unique number identifier (e.g. std::map<vehicle*, type_id>, where type_id is a plain old enum) and perform a simple lookup.
… Or use dynamic_cast, actually.
I normally implement this using a 'kind' member in the base class. I find this has a few advantages:
Performance - no need for virtual function call and dynamic cast
By using a different 'bit' for each class type, then higher level comparisons can be made. For example 'unicycle' and 'bicycle' might both be human powered, so you could easily check for that separately from their main kind.
The kind type would look like the following:
enum Kind {
HUMAN_POWERED = (0x1 << 0),
MOTOR_POWERED = (0x1 << 1),
BICYCLE = (0x1 << 2) | HUMAN_POWERED,
UNICYCLE = (0x1 << 3) | HUMAN_POWERED,
CAR = (0x1 << 4) | MOTOR_POWERED
};
Now it's possible to check that the CAR is not a BICYCLE, but also if two types are MOTOR_POWERED or not!
bool areSameClass (Vehicle const & lhs, Vehicle const & rhs)
{
return (lhs->getKind () & rhs->getKind ()) & (HUMAN_POWERED | MOTOR_POWERED);
}
If you have RTTI enabled in your compiler, you might be able to use the typeid() operator, but this will require your classes to be polymorphic.
Is there a way, I can switch between 2 similar function sets (C/C++) in an effective way?
To explain better what I mean, lets say I have 2 sets of global functions like:
void a_someCoolFunction();
void a_anotherCoolFunction(int withParameters);
…
void b_someCoolFunction();
void b_anotherCoolFunction(int withParameters);
…
And I want to able to "switch" in my program at runtime which one is used. BUT: I dont want to have one if condition at every function, like:
void inline someCoolFunction(){
if(someState = A_STATE){
a_someCoolFunction();
}else{
b_someCoolFunction();
}
}
Because, I expect that every function is called a lot in my mainloop - so It would be preferable if I could do something like this (at start of my mainloop or when someState is changed):
if(someState = A_STATE){
useFunctionsOfType = a;
}else{
useFunctionsOfType = b;
}
and then simply call
useFunctionsOfType _someCoolFunction();
I hope its understandable what I mean… My Background: Im writing an App, that should be able to handle OpenGL ES 1.1 and OpenGL ES 2.0 both properly - but I dont want to write every render Method 2 times (like: renderOpenGL1() and renderOpenGL2() I would rather to write only render()). I already have similiar Methods like: glLoadIdentity(); myLoadIdentity(); … But need a way to switch between these two somehow.
Is there any way to accomplish this in an efficent way?
Several options, including (but not limited to):
Use function pointers.
Wrap them in classes, and use polymorphism.
Have two separate copies of the loop.
But please profile to ensure this is actually a problem, before you make any large changes to your code.
As the question seems to be interested in a C++ solution and no-one has spelt out the polymorphic solution (too obvious?), here goes.
Define an abstract base class with the API you require, and then implement a derived class for each supported implementation:
class OpenGLAbstract
{
public:
virtual ~OpenGLAbstract() {}
virtual void loadIdentity() = 0;
virtual void someFunction() = 0;
};
class OpenGLEs11 : public OpenGLAbstract
{
public:
virtual void loadIdentity()
{
// Call 1.1 API
}
virtual void someFunction()
{
// Call 1.1 API
}
};
class OpenGLEs20 : public OpenGLAbstract
{
public:
virtual void loadIdentity()
{
// Call 2.0 API
}
virtual void someFunction()
{
// Call 2.0 API
}
};
int main()
{
// Select the API to use:
bool want11 = true;
OpenGLAbstract* gl = 0;
if (want11)
gl = new OpenGLEs11;
else
gl = new OpenGLEs20;
// In the main loop.
gl->loadIdentity();
delete gl;
}
Note that this is exactly the sort of thing that C++ was intended for, so if can use C++ here, this is the simplest way to go.
Now a more subtle issue you might face is if your 2.0 version requires the process to load a dynamic linked library at run time with the 2.0 platform implementation. In that case just supporting the API switch is not enough (whatever the solution). Instead put each OpenGL concrete class in its own linked library and in each provide a factory function to create that class:
OpenGlAbstract* create();
Then load the desired library at run time and call the create() method to access the API.
In C (since it seems you want both C and C++) this is done with pointer to functions.
// Globals. Default to the a_ functions
void(*theCoolFunction)() = a_someCoolFunction;
void(*theOtherCoolFunction)(int) = a_anotherCoolFunction;
// In the code ...
{
...
// use the other functions
theCoolFunction = b_someCoolFunction;
theOtherCoolFunction = b_anotherCoolFunction;
...
}
You might probably want to switch those functions in groups, so you better set a array of pointers to functions and pass that array around. If you decide to do so, you might probably want to also define some macro to ease the reading:
void (*functions_a[2])();
void (*functions_b[2])();
void (**functions)() = functions_a;
....
#define theCoolFunction() functions[0]()
#define theOtherCoolFunction(x) functions[1](x)
....
// switch grooup:
functions = functions_b;
but in this case you'll lose the static check on argument types (and you have to initialize the array, of course).
I guess in C++ you will have instatiate two different objects with the same parent class and different implementation for their methods (but I'm no C++ prograammer!)
You could use functions pointers. You can read a lot about them if you google it, but briefly a function pointer stores a pointer to a function's memory address.
Function pointers can be used the same way as a funcion, but can be assigned the address of different functions, making it a somehow "dynamic" function. As an example:
typedef int (*func_t)(int);
int divide(int x) {
return x / 2;
}
int multiply(int x) {
return x * 2;
}
int main() {
func_t f = ÷
f(2); //returns 1
f = &multiply;
f(2); //returns 4
}
Something like boost::function (std::function) would fit the bill. Using your example:
#include <iostream>
#include <boost/function.hpp> //requires boost installation
#include <functional> //c++0x header
void a_coolFunction() {
std::cout << "Calling a_coolFunction()" << std::endl;
}
void a_coolFunction(int param) {
std::cout << "Calling a_coolFunction(" << param << ")" << std::endl;
}
void b_coolFunction() {
std::cout << "Calling b_coolFunction()" << std::endl;
}
void b_coolFunction(int param) {
std::cout << "Calling b_coolFunction(" << param << ")" << std::endl;
}
float mul_ints(int x, int y) {return ((float)x)*y;}
int main() {
std::function<void()> f1; //included in c++0x
boost::function<void(int)> f2; //boost, works with current c++
boost::function<float(int,int)> f3;
//casts are necessary to resolve overloaded functions
//otherwise you don't need them
f1 = static_cast<void(*)()>(a_coolFunction);
f2 = static_cast<void(*)(int)>(a_coolFunction);
f1();
f2(5);
//switching
f1 = static_cast<void(*)()>(b_coolFunction);
f2 = static_cast<void(*)(int)>(b_coolFunction);
f1();
f2(7);
//example from boost::function documentation. No cast required.
f3 = mul_ints;
std::cout << f3(5,3) << std::endl;
}
Compiled with g++-4.4.4, this outputs:
Calling a_coolFunction()
Calling a_coolFunction(5)
Calling b_coolFunction()
Calling b_coolFunction(7)
15
The biggest limitation is that the types of f1,f2, etc cannot change, so any function you assign to them must have the same signature (i.e. void(int) in the case of f2).
The simple way could be storing pointers to functions, and change them od demand.
But the better way is to use something similar to abstract factory design pattern. The nice generic implementation can be found in Loki library.
In C you would typically do this with a struct containing function pointers:
struct functiontable {
void (*someCoolFunction)(void);
void (*anotherCoolFunction)(int);
};
const struct functiontable table_a = { &a_someCoolFunction, &a_anotherCoolFunction };
const struct functiontable table_b = { &b_someCoolFunction, &b_anotherCoolFunction };
const struct functiontable *ftable = NULL;
To switch the active function table, you'd use:
ftable = &table_a;
To call the functions, you'd use:
ftable->someCoolFunction();