access list from class, in parent - c++

I'm new to C++, and have experience with other programmas languages, but I have a question:
How can I access a list from a sub class, from the parent?
Here is my layout:
TutorialApp.cpp with function TutorialApp::update()
In that function I want to access the list mParticles2y from another class
that list is made in: ParticleController.cpp, like this:
std::list<int> mParticles2y;
I've tried accessing the list like this [in TutorialApp]:
mParticleController.mParticles2y.size() [to get it's size]
but that gives me this error:
call of an object of a class type without appropriate operator
So I dont really know where to go from here...
PS: I use mParticleController because that is state in my script:
ParticleController mParticleController;
I hope this is enough info.
PS: I'm not really sure this is called a class, or child, I use these terms because I know them from ActionScript [which works with classes in a similar way]

Your code for the loop that has the errors should look more like this. It may not compile exactly since I can't compile it easily at the moment. This isn't the ideal way to go about it, but it is the minimal impact to your code. I would move this loop to the ParticleController class as a member function that returned true/false to indicate a hit. It would be better encapsulated that way.
for(std::list<int>::iterator yit = mParticleController.mParticles2y.begin(),
std::list<int>::iterator xit = mParticleController.mParticles2x.begin();
yit != mParticleController.mParticles2y.end() && xit != mParticleController.mParticles2x.end();
yit++, xit++)
{
if(
(coordy >= *it) && (coordy <= (*it) + 40) &&
(coordx >= *xit) && (coordx <= (*xit) + 40)
)
{
mParticleController.removeTargetedParticles(i); //remove blokje
score += 1; //score verhogen
}
}

Ok, so this is a shot in the dark, since your question, while very wordy, is short on code necessary to reproduce the issue.
You can only access public members (data or functions) of other objects. That is, in order to access mParticleController.mParticles2y, mParticles2y must be a public member of whatever type mParticleController is of.
Of course, public data member are frowned upon, and for good reasons. A class should represent an abstraction, and if you have a particle controller, it should implement everything necessary to control particles, rather than spilling its guts out in the public for everyone to sift through and take what they need.
This is called encapsulation, and one of the cornerstones of the object oriented paradigm.

size is a method, you need to write size().

The information you provide is somewhat ambiguous, but it looks like you may be attempting to access the private state (the list) of one class (the ParticleController) from another class (The TutorialApp).
I'm assuming the following code structure (note that I haven't tried to compile this so it might not be quite right):
#include <list>
class ParticleController
{
public:
ParticleController() {}
std::list<int> &getParticles2y() const
{
return mParticles2y;
}
private:
std::list<int> mParticles2y;
}
class TutorialApp
{
public:
void update()
{
// ...
ParticleController mParticleController;
//std::list<int> particles2y = mParticleController.mParticles2y; // error - accessing private member of another class
std::list<int> &particles2y = mParticleController.getParticles2y(); // OK
}
}

Related

Two versions of the program depending on the input parameter without code duplication

I am solving the following problem. I am working on an optimization program in C ++ which, depending on the initial settings of the user, uses various regulations (standards) to calculate the target function. Suppose we have a method A based on some norm and a method B based on another norm to calculate the target function. The user is setting the right standard before starting the program. The rest of the code is the same. During optimization, the target function is iteratively called over and over again. Of course, there is a simple solution: each time the target function is called, the IF condition is used to decide which standard to use. But because the program has to make decisions in every iteration, it seems to be ineffective. The second option is to create 2 independent codes and run only the one with the required standard. This, in turn, is ugly in terms of duplicate code.
I imagined that I would create 2 different classes and use the selected class using the IF condition when constructing the object. This would make the program decide only once when creating the object, but during the iteration itself the object would be clearly defined. Unfortunately, this does not work because objects cannot be created in IF conditions.
//-----------------------------------------------------------
// Create object sensor based on input
if(data.sensors_tipe == "Uniaxial_025") Sensor_Uniaxial_025 sensor(data);
else if (data.sensors_tipe == "T_rosette_05") Sensor_T_rosette_05 sensor(data);
else report.error("some error");
// rotation test
int element_index = 1;
double orientation_angle = 3.490658503988659;
sensor.rotate(element_index, orientation_angle);
Another way I would like is to set the correct method using a parameter in the constructor. Unfortunately, that probably isn't possible either.
I am a beginner and I did not find the answer anywhere. So maybe someone can help. Thanks
This is a good job for templates, which are "recipes" to generate code.
The end result will be duplicated machine code, but without the duplication in the source.
template<typename MethodT>
float optimize(const MethodT& method) {
float v = method();
// etc...
}
float methodA();
float methodB();
int main() {
auto a = optimize(methodA);
auto b = optimize(methodB);
}
First, the solution with if may be not that bad. It is branch on each function call, but the branch should be predicted well.
Second, if the functions that implement method A and method B are large enough to miss inlining, use function pointer.
Otherwise, use static polymorphism with templates, method A and method B may be passed via template parameter as functors.
In case, the user can change standard after programm compilation (for example, before each run) you can create interface and 2 child from it.
So, at startup you should create the instance (one of 2) you need through new. And then you can use it.
You can't use that algorithm with stack instances.
One way is to use inheritance.
class Sensor
{
public:
virtual void rotate(int, double) = 0;
};
class Sensor_Uniaxial_025 : public Sensor
{
public:
virtual void rotate(int, double) {/*stuff*/};
};
class Sensor_T_rosette_05 : public Sensor
{
public:
virtual void rotate(int, double) {/*stuff*/};
};
Sensor* sensorToUse;
//-----------------------------------------------------------
// Create object sensor based on input
if(data.sensors_tipe == "Uniaxial_025") sensorToUse = new Sensor_Uniaxial_025(data);
else if (data.sensors_tipe == "T_rosette_05") sensorToUse = new
Sensor_T_rosette_05(data);
else report.error("some error");
// rotation test
int element_index = 1;
double orientation_angle = 3.490658503988659;
sensorToUse->rotate(element_index, orientation_angle);
The example above, with new, comes with serious memory management issues. But if you pre-allocate the sensor for each type, in a single instance, and use a look-up instead it works well.
The alternative is with template. See other answers for these approaches.

Saving in binary files

I've been working on a project for the past few days that involves three linked lists.
Here is an example of the header with the nodes and the lists themselves:
class nodeA
{
int data1;
double data2;
nodeA* next;
}
class listA
{
nodeA* headA;
...
}
class nodeB
{
int data3;
double data4;
nodeB* nextB;
}
class listB
{
nodeB* headB;
...
}
class nodeC
{
int data5;
double data6;
nodeC* nextC;
}
class listC
{
nodeC* headC;
...
}
What i'd like to know is how can i save the lists that i declare in my main so that if i close the program and then open it again i can recover the lists data
So lista_vendas::novaVenda needs to call lista_produto::escolheProduto.
To call lista_produto::escolheProduto you need a lista_produto object. Where are you going to get that lista_produto object from?
There's really only three ways this can be done. I don't know which way is the correct way for you, but I'll list them and you can decide.
1) Have a lista_produto global variable, a global list of products. Then lista_vendas::novaVenda can use the global lista_produto to call lista_produto::escolheProduto. This is the simple solution, but global variables are rightly considered bad style. It also means that you program can only have one list of products, is that a problem? Think carefully before trying this solution.
2) Have a lista_produto as a member variable of lista_vendas or no_vendas. I guessing here but perhaps something like this
class no_vendas
{
public:
unsigned int codigoVenda, dia, mes, ano, numeroItens;
double precoTotal;
lista_produto productList; // list of products
no_vendas* proxi; //referencia para o proximo no
};
Now each vendor has a list of products, which makes sense. So lista_vendas::novaVenda now has access to a lista_produto in each no_vendas and it can use that to call lista_produto::escolheProduto. If this makes sense then this is problably the best solution.
3) Pass a lista_produto as a parameter to lista_vendas::novaVenda. Like this
void novaVenda(unsigned int codigoVenda, lista_produto* productList);
So whatever code calls lista_vendas::novaVenda must also supply the lista_produto that it needs.
As I said I don't know which of these possibilities is correct, because I don't know what you are trying to do (and I don't speak Spanish). But this is a problem in the relationships between your different objects. It's up to you to design your classes so that they can access the different objects that they need to work.
You mentioned inheritance in your title, but this doesn't feel like the right thing to do in this case.
This won't help you with your concrete problem at hand but I think you should use standard containers like std::vector<>. Implementing your own linked list is a nice finger exercise but seldom really necessary. That said, you should use std::vector<no_produto> instead of lista_produto:
#include <vector>
std::vector<no_produto> my_lista_produto;
// fill the vector:
my_lista_produto.push_back(my_no_produto_1);
my_lista_produto.push_back(my_no_produto_2);
// ...
// retrieve one item:
const no_produto &p = my_lista_produto[1];
// clear all items:
my_lista_produto.clear();
A complete list of all available methods can be found here.
Concerning your question: The question title mentions inheritance but there isn't any inheritance used in your example. In order to derive class B from class A you have to write
class A {
public:
void func();
};
class B : public A {
public:
void gunc();
};
This means essentially, B can be treated as an A. B contains the content of A and exposes the public interface of A by itself. Thus we can write:
void B::gunc() {
func();
}
even though B never defines the method func(), it inherited the method from A. I suspect, that you didn't inherit your classes properly from each other.
In addition to my initial thoughts about writing you own linked lists, please consider also composition instead of inheritance. You can find more information about the topic at Wikipedia or on Stack Overflow.

c++ particle system inheritance

i'm creating particle system and i want to have possibility to choose what kind of object will be showing on the screen (like simply pixels, or circle shapes). I have one class in which all parameters are stored (ParticleSettings), but without those entities that stores points, or circle shapes, etc. I thought that i may create pure virtual class (ParticlesInterface) as a base class, and its derived classes like ParticlesVertex, or ParticlesCircles for storing those drawable objects. It is something like that:
class ParticlesInterface
{
protected:
std::vector<ParticleSettings> m_particleAttributes;
public:
ParticlesInterface(long int amount = 100, sf::Vector2f position = { 0.0,0.0 });
const std::vector<ParticleSettings>& getParticleAttributes() { return m_particleAttributes; }
...
}
and :
class ParticlesVertex : public ParticlesInterface
{
private:
std::vector<sf::Vertex> m_particleVertex;
public:
ParticlesVertex(long int amount = 100, sf::Vector2f position = { 0.0,0.0 });
std::vector<sf::Vertex>& getParticleVertex() { return m_particleVertex; }
...
}
So... I know that i do not have access to getParticleVertex() method by using polimorphism. And I really want to have that access. I want to ask if there is any better solution for that. I have really bad times with decide how to connect all that together. I mean i was thinking also about using template classes but i need it to be dynamic binding not static. I thought that this idea of polimorphism will be okay, but i'm really need to have access to that method in that option. Can you please help me how it should be done? I want to know what is the best approach here, and also if there is any good answer to that problem i have if i decide to make that this way that i show you above.
From the sounds of it, the ParticlesInterface abstract class doesn't just have a virtual getParticleVertex because that doesn't make sense in general, only for the specific type ParticlesVertex, or maybe a group of related types.
The recommended approach here is: Any time you need code that does different things depending on the actual concrete type, make those "different things" a virtual function in the interface.
So starting from:
void GraphicsDriver::drawUpdate(ParticlesInterface &particles) {
if (auto* vparticles = dynamic_cast<ParticlesVertex*>(&particles)) {
for (sf::Vertex v : vparticles->getParticleVertex()) {
draw_one_vertex(v, getCanvas());
}
} else if (auto* cparticles = dynamic_cast<ParticlesCircle*>(&particles)) {
for (CircleWidget& c : cparticles->getParticleCircles()) {
draw_one_circle(c, getCanvas());
}
}
// else ... ?
}
(CircleWidget is made up. I'm not familiar with sf, but that's not the point here.)
Since getParticleVertex doesn't make sense for every kind of ParticleInterface, any code that would use it from the interface will necessarily have some sort of if-like check, and a dynamic_cast to get the actual data. The drawUpdate above also isn't extensible if more types are ever needed. Even if there's a generic else which "should" handle everything else, the fact one type needed something custom hints that some other future type or a change to an existing type might want its own custom behavior at that point too. Instead, change from a thing code does with the interface to a thing the interface can be asked to do:
class ParticlesInterface {
// ...
public:
virtual void drawUpdate(CanvasWidget& canvas) = 0;
// ...
};
class ParticlesVertex {
// ...
void drawUpdate(CanvasWidget& canvas) override;
// ...
};
class ParticlesCircle {
// ...
void drawUpdate(CanvasWidget& canvas) override;
// ...
};
Now the particles classes are more "alive" - they actively do things, rather than just being acted on.
For another example, say you find ParticlesCircle, but not ParticlesVertex, needs to make some member data updates whenever the coordinates are changed. You could add a virtual void coordChangeCB() {} to ParticlesInterface and call it after each motion model tick or whenever. With the {} empty definition in the interface class, any class like ParticlesVertex that doesn't care about that callback doesn't need to override it.
Do try to keep the interface's virtual functions simple in intent, following the Single Responsibility Principle. If you can't write in a sentence or two what the purpose or expected behavior of the function is in general, it might be too complicated, and maybe it could more easily be thought of in smaller steps. Or if you find the virtual overrides in multiple classes have similar patterns, maybe some smaller pieces within those implementations could be meaningful virtual functions; and the larger function might or might not stay virtual, depending on whether what remains can be considered really universal for the interface.
(Programming best practices are advice, backed by good reasons, but not absolute laws: I'm not going to say "NEVER use dynamic_cast". Sometimes for various reasons it can make sense to break the rules.)

A better design pattern than factory?

In the code I am now creating, I have an object that can belong to two discrete types, differentiated by serial number. Something like this:
class Chips {
public:
Chips(int shelf) {m_nShelf = shelf;}
Chips(string sSerial) {m_sSerial = sSerial;}
virtual string GetFlavour() = 0;
virtual int GetShelf() {return m_nShelf;}
protected:
string m_sSerial;
int m_nShelf;
}
class Lays : Chips {
string GetFlavour()
{
if (m_sSerial[0] == '0') return "Cool ranch";
else return "";
}
}
class Pringles : Chips {
string GetFlavour()
{
if (m_sSerial.find("cool") != -1) return "Cool ranch";
else return "";
}
}
Now, the obvious choice to implement this would be using a factory design pattern. Checking manually which serial belongs to which class type wouldn't be too difficult.
However, this requires having a class that knows all the other classes and refers to them by name, which is hardly truly generic, especially if I end up having to add a whole bunch of subclasses.
To complicate things further, I may have to keep around an object for a while before I know its actual serial number, which means I may have to write the base class full of dummy functions rather than keeping it abstract and somehow replace it with an instance of one of the child classes when I do get the serial. This is also less than ideal.
Is factory design pattern truly the best way to deal with this, or does anyone have a better idea?
You can create a factory which knows only the Base class, like this:
add pure virtual method to base class: virtual Chips* clone() const=0; and implement it for all derives, just like operator= but to return pointer to a new derived. (if you have destructor, it should be virtual too)
now you can define a factory class:
Class ChipsFactory{
std::map<std::string,Chips*> m_chipsTypes;
public:
~ChipsFactory(){
//delete all pointers... I'm assuming all are dynamically allocated.
for( std::map<std::string,Chips*>::iterator it = m_chipsTypes.begin();
it!=m_chipsTypes.end(); it++) {
delete it->second;
}
}
//use this method to init every type you have
void AddChipsType(const std::string& serial, Chips* c){
m_chipsTypes[serial] = c;
}
//use this to generate object
Chips* CreateObject(const std::string& serial){
std::map<std::string,Chips*>::iterator it = m_chipsTypes.find(serial);
if(it == m_chipsTypes.end()){
return NULL;
}else{
return it->clone();
}
}
};
Initialize the factory with all types, and you can get pointers for the initialized objects types from it.
From the comments, I think you're after something like this:
class ISerialNumber
{
public:
static ISerialNumber* Create( const string& number )
{
// instantiate and return a concrete class that
// derives from ISerialNumber, or NULL
}
virtual void DoSerialNumberTypeStuff() = 0;
};
class SerialNumberedObject
{
public:
bool Initialise( const string& serialNum )
{
m_pNumber = ISerialNumber::Create( serialNum );
return m_pNumber != NULL;
}
void DoThings()
{
m_pNumber->DoSerialNumberTypeStuff();
}
private:
ISerialNumber* m_pNumber;
};
(As this was a question on more advanced concepts, protecting from null/invalid pointer issues is left as an exercise for the reader.)
Why bother with inheritance here? As far as I can see the behaviour is the same for all Chips instances. That behaviour is that the flavour is defined by the serial number.
If the serial number only changes a couple of things then you can inject or lookup the behaviours (std::function) at runtime based on the serial number using a simple map (why complicate things!). This way common behaviours are shared among different chips via their serial number mappings.
If the serial number changes a LOT of things, then I think you have the design a bit backwards. In that case what you really have is the serial number defining a configuration of the Chips, and your design should reflect that. Like this:
class SerialNumber {
public:
// Maybe use a builder along with default values
SerialNumber( .... );
// All getters, no setters.
string getFlavour() const;
private:
string flavour;
// others (package colour, price, promotion, target country etc...)
}
class Chips {
public:
// Do not own the serial number... 'tis shared.
Chips(std::shared_ptr<SerialNumber> poSerial):m_poSerial{poSerial}{}
Chips(int shelf, SerialNumber oSerial):m_poSerial{oSerial}, m_nShelf{shelf}{}
string GetFlavour() {return m_poSerial->getFlavour()};
int GetShelf() {return m_nShelf;}
protected:
std::shared_ptr<SerialNumber> m_poSerial;
int m_nShelf;
}
// stores std::shared_ptr but you could also use one of the shared containers from boost.
Chips pringles{ chipMap.at("standard pringles - sour cream") };
This way once you have a set of SerialNumbers for your products then the product behaviour does not change. The only change is the "configuration" which is encapsulated in the SerialNumber. Means that the Chips class doesn't need to change.
Anyway, somewhere someone needs to know how to build the class. Of course you could you template based injection as well but your code would need to inject the correct type.
One last idea. If SerialNumber ctor took a string (XML or JSON for example) then you could have your program read the configurations at runtime, after they have been defined by a manager type person. This would decouple the business needs from your code, and that would be a robust way to future-proof.
Oh... and I would recommend NOT using Hungarian notation. If you change the type of an object or parameter you also have to change the name. Worse you could forget to change them and other will make incorrect assumptions. Unless you are using vim/notepad to program with then the IDE will give you that info in a clearer manner.
#user1158692 - The party instantiating Chips only needs to know about SerialNumber in one of my proposed designs, and that proposed design stipulates that the SerialNumber class acts to configure the Chips class. In that case the person using Chips SHOULD know about SerialNumber because of their intimate relationship. The intimiate relationship between the classes is exactly the reason why it should be injected via constructor. Of course it is very very simple to change this to use a setter instead if necessary, but this is something I would discourage, due to the represented relationship.
I really doubt that it is absolutely necessary to create the instances of chips without knowing the serial number. I would imagine that this is an application issue rather than one that is required by the design of the class. Also, the class is not very usable without SerialNumber and if you did allow construction of the class without SerialNumber you would either need to use a default version (requiring Chips to know how to construct one of these or using a global reference!) or you would end up polluting the class with a lot of checking.
As for you complaint regarding the shared_ptr... how on earth to you propose that the ownership semantics and responsibilities are clarified? Perhaps raw pointers would be your solution but that is dangerous and unclear. The shared_ptr clearly lets designers know that they do not own the pointer and are not responsible for it.

C++ RTTI Viable Examples [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am familiar with C++ RTTI, and find the concept interesting.
Still there exist a lot of more ways to abuse it than to use it correctly (the RTTI-switch dread comes to mind). As a developer, I found (and used) only two viable uses for it (more exactly, one and a half).
Could you share some of the ways RTTI is a viable solution to a problem, with example code/pseudo-code included?
Note: The aim is to have a repository of viable examples a junior developer can consult, criticize and learn from.
Edit: You'll find below code using C++ RTTI
// A has a virtual destructor (i.e. is polymorphic)
// B has a virtual destructor (i.e. is polymorphic)
// B does (or does not ... pick your poison) inherits from A
void doSomething(A * a)
{
// typeid()::name() returns the "name" of the object (not portable)
std::cout << "a is [" << typeid(*a).name() << "]"<< std::endl ;
// the dynamic_cast of a pointer to another will return NULL is
// the conversion is not possible
if(B * b = dynamic_cast<B *>(a))
{
std::cout << "a is b" << std::endl ;
}
else
{
std::cout << "a is NOT b" << std::endl ;
}
}
Acyclic Visitor (pdf) is a great use of it.
How about the boost::any object!
This basically uses the RTTI info to store any object and the retrieve that object use boost::any_cast<>.
You can use RTTI with dynamic_cast to get a pointer to a derived class in order to use it to call a fast, type specialized algorithm. And instead of using the virtual methods through the base class, it will make direct and inlined calls.
This sped things up for me a lot using GCC. Visual Studio didn't seem to do as well, it may have a slower dynamic_cast lookup.
Example:
D* obj = dynamic_cast<D*>(base);
if (obj) {
for(unsigned i=0; i<1000; ++i)
f(obj->D::key(i));
}
} else {
for(unsigned i=0; i<1000; ++i)
f(base->key(i));
}
}
I cant say I've ever found a use for in in real life but RTTI is mentioned in Effective C++ as a possible solution to multi-methods in C++. This is because method dispatch is done on the dynamic type of the this parameter but the static type of the arguments.
class base
{
void foo(base *b) = 0; // dynamic on the parameter type as well
};
class B : public base {...}
class B1 : public B {...}
class B2 : public B {...}
class A : public base
{
void foo(base *b)
{
if (B1 *b1=dynamic_cast<B1*>(b))
doFoo(b1);
else if (B2 *b2=dynamic_cast<B2*>(b))
doFoo(b2);
}
};
I worked on an aircraft simulation once, that had what they (somewhat confusingly) referred to as a "Simulation Database". You could register variables like floats or ints or strings in it, and people could search for them by name, and pull out a reference to them. You could also register a model (an object of a class descended from "SimModel"). The way I used RTTI, was to make it so you could search for models that implement a given interface:
SimModel* SimDatabase::FindModel<type*>(char* name="")
{
foreach(SimModel* mo in ModelList)
if(name == "" || mo->name eq name)
{
if(dynamic_cast<type*>mo != NULL)
{
return dynamic_cast<type*>mo;
}
}
return NULL;
}
The SimModel base class:
class public SimModel
{
public:
void RunModel()=0;
};
An example interface might be "EngineModel":
class EngineModelInterface : public SimModel
{
public:
float RPM()=0;
float FuelFlow()=0;
void SetThrottle(float setting)=0;
};
Now, to make a Lycoming and Continental engine:
class LycomingIO540 : public EngineModelInterface
{
public:
float RPM()
{
return rpm;
}
float FuelFlow()
{
return throttleSetting * 10.0;
}
void SetThrottle(float setting)
{
throttleSetting = setting
}
void RunModel() // from SimModel base class
{
if(throttleSetting > 0.5)
rpm += 1;
else
rpm -= 1;
}
private:
float rpm, throttleSetting;
};
class Continental350: public EngineModelInterface
{
public:
float RPM()
{
return rand();
}
float FuelFlow()
{
return rand;
}
void SetThrottle(float setting)
{
}
void RunModel() // from SimModel base class
{
}
};
Now, here's some code where somebody wants an engine:
.
.
EngineModelInterface * eng = simDB.FindModel<EngineModelInterface *>();
.
.
fuel = fuel - deltaTime * eng->FuelFlow();
.
.
.
Code is pretty pseudo, but I hope it gets the idea across. One developer can write code that depends on having an Engine, but as long as it has something that implements the engine interface, it doesn't care what it is. So the code that updates the amount of fuel in the tanks is completely decoupled from everything except the FindModel<>() function, and the pure virtual EngineModel interface that he's interested in using. Somebody a year later can make a new engine model, register it with the SimulationDatabase, and the guy above who updates fuel will start using it automatically. I actually made it so you could load new models as plugins (DLLs) at runtime, and once they are registered in the SimulationDatabase, they could be found with FindModel<>(), even though the code that was looking for them was compiled and built into a DLL months before the new DLL existed. You could also add new Interfaces that derive from SimModel, with something that implements them in one DLL, something that searches for them in another DLL, and once you load both DLLs, one can do a FindModel<>() to get the model in the other. Even though the Interface itself didn't even exist when the main app was built.
Parenthetically, RTTI doesn't always work across DLL boundaries. Since I was using Qt anyway, I used qobject_cast instead of dynamic_cast. Every class had to inherit from QObject (and get moc'd), but the qobject meta-data was always available. If you don't care about DLLs, or you are using a toolchain where RTTI does work across DLL boundaries (type comparisons based on string comparisons instead of hashes or whatever), then all of the above with dynamic_cast will work just fine.
I use it in a class tree which serializes to a XML file. On the de-serialization, the parser class returns a pointer to the base class which has a enumeration for the type of the subclass (because you don't know which type it is until you parse it). If the code using the object needs to reference subclass specific elements, it switches on the enum value and dynamic_cast's to the subclass (which was created by the parser). This way the code can check to ensure that the parser didn't have an error and a mismatch between the enum value and the class instance type returned. Virtual functions are also not sufficient because you might have subclass specific data you need to get to.
This is just one example of where RTTI could be useful; it's perhaps not the most elegant way to solve the problem, but using RTTI makes the application more robust when using this pattern.
Sometimes static_cast and C-style casts just aren't enough and you need dynamic_cast, an example of this is when you have the dreaded diamond shaped hierarchy (image from Wikipedia).
struct top {
};
struct left : top {
int i;
left() : i(42) {}
};
struct right : top {
std::string name;
right() : name("plonk") { }
};
struct bottom : left, right {
};
bottom b;
left* p = &b;
//right* r = static_cast<right*>(p); // Compilation error!
//right* r = (right*)p; // Gives bad pointer silently
right* r = dynamic_cast<right*>(p); // OK
Use cases I have in my projects (if you know any better solution for specific cases, please comment):
The same thing as 1800 INFORMATION has already mentioned:
You'll need a dynamic_cast for the operator== or operator< implementation for derived classes. Or at least I don't know any other way.
If you want to implement something like boost::any or some other variant container.
In one game in a Client class which had a std::set<Player*> (possible instances are NetPlayer and LocalPlayer) (which could have at most one LocalPlayer), I needed a function LocalPlayer* Client::localPlayer(). This function is very rarely used so I wanted to avoid to clutter Client with an additional local member variable and all the additional code to handle this.
I have some Variable abstract class with several implementations. All registered Variables are in some std::set<Variable*> vars. And there are several builtin vars of the type BuiltinVar which are saved in a std::vector<BuiltinVar> builtins. In some cases, I have a Variable* and need to check if it is a BuiltinVar* and inside builtins. I could either do this via some memory-range check or via dynamic_cast (I can be sure in any case that all instances of BuiltinVar are in this vector).
I have a gridded collection of GameObjects and I need to check if there is a Player object (a specialized GameObject) inside one grid. I could have a function bool GameObject::isPlayer() which always returns false except for Player or I could use RTTI. There are many more examples like this where people often are implementing functions like Object::isOfTypeXY() and the base class gets very cluttered because of this.
This is also sometimes the case for other very special functions like Object::checkScore_doThisActionOnlyIfIAmAPlayer(). There is some common sense needed to decide when it actually make sense to have such a function in the base class and when not.
Sometimes I use it for assertions or runtime security checks.
Sometimes I need to store a pointer of some data in some data field of some C library (for example SDL or what not) and I get it somewhere else later on or as a callback. I do a dynamic_cast here just to be sure I get what I expect.
I have some TaskManager class which executes some queue of Tasks. For some Tasks, when I am adding them to the list, I want to delete other Tasks of the same type from the queue.
I used RTTI when doing some canvas-based work with Qt several years ago. It was darn convenient when doing hit-tests on objects to employ RTTI to determine what I was going to do with the shape I'd 'hit'. But I haven't used it otherwise in production code.
I'm using it with Dynamic Double Dispatch and Templates. Basically, it gives the ability to observe/listen to only the interesting parts of an object.