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.
Related
Is there any technique or compiler extension keyword to declare class member variables inside class member functions? Something like
struct test_t{
void operator ()(){
instance_local int i = 0;
}
};
The best that came in my mind was using thread_local and then executing the member function inside another thread, but this would be too ugly to be useful.
EDIT: example
Well I'm really sorry for the following probably confusing example (it is related to my question yesterday Is there any problem in jumping into if(false) block?). I really tried to make a less confusing up...
#include <iostream>
#define instance_local thread_local
struct A{
A(int i) :
i(i)
{
}
void dosomethinguseful(){
std::cout << i << std::endl;
}
int i;
};
struct task1{
int part;
task1() : part(0){}
void operator ()(){
int result_of_calculation;
switch (part) {
case 0:{
//DO SOME CALCULATION
result_of_calculation = 5;
instance_local A a(result_of_calculation);
if(false)
case 1:{ a.dosomethinguseful();}
part++;
}
default:
break;
}
}
};
int main(){
task1 t;
t();
t();
return 0;
}
instance_local A a(result_of_calculation); that is what i could get from such a keyword instead of making a smart pointer for a.
You're describing a coroutine. Here a rough draft of what it could look like (I'm not an expert in coroutine)
auto task1() -> some_awaitable_type {
result_of_calculation = 5;
A a(result_of_calculation);
co_yield;
a.dosomethinguseful();
}
This could be called like this:
some_awaitable_type maybe_do_something = task1();
// calculation done here
// dosomethinguseful called here
co_await maybe_do_something();
There is not. The compiler needs to know the structure of the class without compiling all the method implementations. If you could slip instance_local int foo into a method body, that would make the size of the data structure 4 bytes larger.
On a more principled level, it's not good to hide data. The equivalent feature for global variables that you might be thinking of, static local variables, is a carryover from C that is widely considered to be an anti-pattern:
Why are static variables considered evil?
Not directly, no.
You could define a:
static std::map<test_t*, int> is;
…where the first part of each element is a this pointer.
But, why?
Make a member variable.
I am learning how c++ is compiled into assembly and I found how exceptions works under the hood very interesting. If its okay to have more then one execution paths for exceptions why not for normal functions.
For example, lets say you have a function that can return a pointer to class A or something derived from A. The way your supposed to do it is with RTTI.
But why not, instead, have the called function, after computing the return value, jump back to the caller function into the specific location that matchs up with the return type. Like how exceptions, the execution flow can go normal or, if it throws, it lands in one of your catch handlers.
Here is my code:
class A
{
public:
virtual int GetValue() { return 0; }
};
class B : public A
{
public:
int VarB;
int GetValue() override { return VarB; }
};
class C : public A
{
public:
int VarC;
int GetValue() override { return VarC; }
};
A* Foo(int i)
{
if(i == 1) return new B;
if(i == 2)return new C;
return new A;
}
void main()
{
A* a = Foo(2);
if(B* b = dynamic_cast<B*>(a))
{
b->VarB = 1;
}
else if(C* c = dynamic_cast<C*>(a)) // Line 36
{
c->VarC = 2;
}
else
{
assert(a->GetValue() == 0);
}
}
So instead of doing it with RTTI and dynamic_cast checks, why not have the Foo function just jump to the appropriate location in main. So in this case Foo returns a pointer to C, Foo should instead jump to line 36 directly.
Whats wrong with this? Why aren't people doing this? Is there a performance reason? I would think this would be cheaper then RTTI.
Or is this just a language limitation, regardless if its a good idea or not?
First of all, there are million different ways of defining the language. C++ is defined as it is defined. Nice or not really does not matter. If you want to improve the language, you are free to write a proposal to C++ committee. They will review it and maybe include in future standards. Sometimes this happens.
Second, although exceptions are dispatched under the hood, there are no strong reasons to think that this is more efficient comparing your handwritten code that uses RTTI. Exception dispatch still requires CPU cycles. There is no miracle there. The real difference is that for using RTTI you need to write the code yourself, while the exception dispatch code is generated for you by compiler.
You may want to call you function 10000 times and find out what will run faster: RTTI based code or exception dispatch.
I've two class named 'Expression' and 'BinExp' as following codes:
class Expression
{
public:
virtual BinExp* IsBinaryExp() { return NULL; }
};
class BinExp : public Expression
{
public:
virtual BinExp* IsBinaryExp() { return this; }
};
As example, I've a pointer variable type of Expression* but initialized as new BinExp and send as argument to a analyse function as following code:
int main()
{
Expression* e = new BinExp;
analyse(e);
}
Inside the analyse function, I need to know whether the e is pointer to Expression type or BinExp type. In my hand, there is three way to do this.
First:
BinExp* be = e->IsBinaryExp();
if ( be )
{
printf("Yes, `e` is a binary expression\n");
}
Second:
BinExp* be = dynamic_cast<BinExp*>(e);
if ( be )
{
printf("Yes, `e` is a binary expression\n");
}
And the third:
if ( typeid(*e) == typeid(BinExp) )
{
BinExp* be = e->IsBinaryExp(); // or dynamic_cast<BinExp*>(e);
printf("Yes, `e` is a binary expression\n");
}
But I want to know which of those ways ( or any other ) will be more efficient and effective when I need to perform the checking frequently inside a loop where performance is a matter. Any kind of suggestion I will appreciate.
The fastest way would be to keep a member variable , say an enum , then define in the base class a inline getter, then you can compare if the result is what you expect.
Sample (uncompiled, some errors might occur) :
enum eExpTypes {
ET_UNDEFINED,
ET_BINARY
}
class Expresion
{
protected:
eExpTypes myType;
public:
Expresion(): myType(ET_UNDEFINED){};
inline eExpTypes getType(){return myType;};
}
class BinExpresion : public Expresion
{
public:
BinExpresion():myType(ET_BINARY){};
}
Performance gain :
you will take out two indiections : from pointer to vfptable , from vfptable to function
your class size will be less if the type function is the only virtual function
Dynamic cast is usually slower then making your own type check mechanism, so in case of your 3 examples the first one should be the fastest.
The fastest will be:
e->printIsBinExp();
Where you make that virtual method that either prints or is a noop.
I'm only partially joking. The point of virtual methods is to encapsulate different types' handling of a particular method - not to write a program to just do a runtime switch on what the different runtime types could be.
Suppose the dynamic_cast was fastest. Would you then write:
if (BinExp* be = dynamic_cast<BinExp*>(e)) {
// ...
}
else if (UnExp* ue = dynamic_cast<UnExp*>(e)) {
// ...
}
else if (TernExp* te = dynamic_cast<TernExp*>(e)) {
// ...
}
Hopefully not. That code is going to be very brittle. You'll definitely want to come up with a design such that:
e->eval();
just does the right thing as a single virtual call.
Number 3 is the most elegant.
To find out if or which one is the most efficient, some simple code can be used to measure execution time of each case...
#include <iostream>
#include <chrono>
/*
Case
*/
int main()
{
const clock_t begin_time = clock();
// Case
std::cout << float(clock() - begin_time) / CLOCKS_PER_SEC;
system("pause");
return 0;
}
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
I know about the existence of static_cast, dynamic_cast. But I can't seem to find out a concrete reason to convince myself about why cast from base to derive or vice versa?
Any example in code would be appreciated.
UPDATE
class Base
{
public:
void foo();
private:
int _x;
};
class Derive: Base
{
};
Base *b = new Derive; //will b behave the same as if it's a Derive *?
Derive *d = new Base; //I think d can't behave like a Derive * but Base *, right?
Actually, those casts are obvious marks of something unsual going on in the code, so in a perfect world, you shouldn't use them.
But in some cases they are the right tool for the job.
For static_cast, there are basically 2 cases:
1. Primitive conversion.
When you really need some integer number to be processed in a calculus involving floats.
float ratio = static_cast<float>( pixel_pos.x ) / static_cast<float>( pixel_pos.y ); // x and y are integers because pixel positions are absolute, but we need to get a floating point value here
2. You got an object from some external API and you want to get the specific child-type.
Thing* thing = factory.create( "shoe" ); // Even if I don't have it's real type, I know it's a shoe!
Shoe* shoe = static_cast<Shoe*>( thing ); // I need to use Shoe interface so lets cast it.
If you designed the system, maybe you could have done it better to avoid the cast. But if you didn't and the API you're using provide the base type as a way for you to work with it, then you don't have any other choice than to cast.
static_cast is useful also because it lets you assume something at compile time, so you should use it first because it requires you to be sure about what you are doing.
3.You don't know what is the real type of the object.
However, there is a specific case when you need to know the real type at runtime because there is no way for you to know it at another time. Typical case is when you're receiving some kind of objects from an external system and there is no other information about the real type of the object
void on_something_happen( const Event& event ) // callback triggered when an event occured in the library system this callback is plugged in
{
// here I want to manage two cases
ThingEvent* thing_event = dynamic_cast<ThingEvent*>( &event );
if( thing_event )
{
// do my thing
}
else
{
// ok this event HAVE TO be a FooEvent, otherwise this should crash
FooEvent& foo_event = dynamic_cast<FooEvent&>( event );
// do my thing
}
}
suppose you have:
struct A {
int i;
};
struct B : A {
char c;
};
struct C : A {
double d;
};
And some function f() returning a pointer to A, for which you don't know the definition.
When you do:
A * a = f();
How do you know what you can do with a? According to the definition above every B and C is also an A, so you know that if a is not null you can use its i data member without problems. On the other hand, in order to use either c or d you need to know the actual type of a, and that is achieved with dynamic_cast.
Let's suppose you know that a is actually a pointer to B. What you can do is:
B * b = dynamic_cast<B *>(a);
if ( b != 0 )
b->c = 'd';
(Yes, I know we assumed you know it, but such assumptions never hold forever...)
The typical situation is the need to add an operation to an existing data type, but you can't add it directly.
Suppose you have this class structure:
struct Base {
virtual doSomething() = 0;
};
struct Derived1 : Base {
virtual doSomething();
int x,y;
};
struct Derived2 : Base {
virtual doSomething();
float a,b;
};
Now you are writing a function that is passed a Base&:
void f(Base& base);
You want to be able to print information about base, but for whatever reason, you aren't allowed to modify Base to add this operation (it is part of a commercial library, for example). In that case you may have to do something like this:
void f(Base& base)
{
if (Derived1* p=dynamic_cast<Derived1*>(&base)) {
cout << "Derived1{" << p->x << "," << p->y << "}\n";
}
else if (Derived2* p=dynamic_cast<Derived2*>(&base)) {
cout << "Derived2{" << p->a << "," << p->b << "}\n";
}
else {
cout << "Unknown type\n";
}
}
This is typically considered bad style in an object-oriented language though. One problem is that if you add a new class to your hierarchy, then the compiler won't help you find the places where you need to add code to handle operations on instances of that new class.