Switching between different types of pointers to objects - c++

So far I have been using dynamic casting. But this comes with it's pros and cons. It seems that is a good thing NOT to use this too much. The examples on this topic, that I have found, are usually with classes that have little differences. But in my case, the "child" classes have very little similarities.
The code in this post is NOT from the project. It's only used for examples.
I am making a trading system for a game and there will be many more systems in the project. There are many different items that do many different things- equipment, modifications, resources. No matter how different they are, they all have a price and they can all be putted in an inventory, no matter what they are. But this is where are the similarities end, including the overridden methods.
Afterwards the different items are used in completely different ways. At first the different types of items were sorted in separate arrays of pointers from different types- one for the equipment, one for the modifications, e.t.c. To put something in an inventory I only use a single method- addToInventory(Item* item) . Since the item must be placed in the right array, I use dynamic casting- I convert Item* item to (for example) Equipment* equi, so I can add it to the Equipment array. I want to do it in the same method, because it's more intuitive and otherwise the different methods would have similar code.
addToInventory(Item* item)
{
if (item->type == 'e')
{
Equipment* newEquip = dynamic_cast<Equipment*>(item);
equipmentArr.add(newEquip);//thous arrays are dynamic- the reason I needed to make the conversion explained later
}
else if (item->type == 'm')
{
Modification* newMod = dynamic_cast<Modification*>(item);
modificationArr.add(newEquip);
}
//and so on...
}
Later I would want to add a modification to a piece of equipment- Weapon::addMod(Modification* mod) . And in this method I use other methods and variables that are found ONLY in the Weapon class.
addMod (Modification* mod)
{//all are found ONLY in class Weapon
mod[modCount] = mod; //an array of Modification* pointers
modCount++;
calcEfficiency();
}
But when I want to make the simple thing to print an inventory, I either have to copy-paste and edit some code for converting the pointers in the arrays, so I can pass them in the same printing method, or copy-paste and edit the same code for printing. There is a third option- to make the arrays to all arrays of pointers to Item objects. I tried the last option.
It got rid of the casting in addToInventory(Item* item), yay! But it caused the need to use casting EVERY time I need to call methods such as Weapon::addMod(Modification* mod) and in other places. Otherwise, I will need to put the casting within the method, but I want the method to explicitly take an Equipment* argument.
The project is still really early in development, so I don't know how much more I might need to use casting, so I can switch back and forth between different types of pointers when needed.
So, in a similar case, how should I switch between different types of pointers?

You may want to represent the traits (namely Equipment and Modification) of your (broad) Item implementations as pure virtual classes (i.e. interfaces). This way dynamic casting and dynamic cast checks for these interfaces is OK and will lower the noise to handle for actual implementations of Equipment and Modification.
Another way is to use the CRTP pattern and static_cast<Interface*> to have compile time checks for your interfaces.
Depends on your use case which way is more appropriate. As a rule of thumb:
Mostly static configuration => Do at compile time
More dynamic configuration (run time allocated instances) => Do at runtime

Related

Big projects that require very good performance really don't use polymorphism?

For quite some time I have been interested in perfomance in C ++.
A lot of things keep coming up, whether in conferences or in books:
Do not use a virtual function, have the data in the cache, the branches etc.
There are many benchmarks with examples of video games to show the differences in performance.
The thing is, the examples are always very simple.
How does that really work in code that is more than 20 lines? in AAA video games, finance etc.
If I have 100 types of objects that have different update, different behavior and other joys, it's easy to set up via polymorphism or function pointers.
Now, by following the advice given to make a powerful code, the above options are not possible.
We will therefore prefer to have 100 arrays that we will update separately.
We will have good access to the cache, the functions will probably be inline etc. in short, the performance will in principle be better.
So, I have 100 arrays and 100 differents functions that i will have to call at each frame.
The tables dynamically change depending on what happens, new players appear, a monster dies etc.
Some array will have 0 elements active, others 10...
I would call functions that will have no work (array without active element) but I have no choice, I have to have a flag or look if elements are active or not in my array.
I end up with something like this:
obj1update ();
obje2update ();
....
obj1behavior ();
obj2behavior ();
....
obj1render ();
obj2render ();
.....
objectxy ();
....
Of course, there will undoubtedly be a function which manages all the update calls on the objects, one for the behavior etc but to simplify it gives as above.
To stay in the video game, if the x action of a player causes the arrival of y monsters, there are several types of monsters which have different functions.
We will therefore put the monsters in our tables and this time the functions dealing with these monsters will have work.
We can use the ECS pattern or a derivative but they will potentially have very different behaviors (an ia that directs them or other), different components and therefore different functions will be needed to process them.
They will be called hard in the code since we don't have polymorphism or function pointers and we will have to check at each frame if they have something to process or not.
Is it really done that way? suppose i have 500 types? 1000 ?
Edit:
Lots of comments so I'll get back to you here.
As Federico said, I want to know if these recommendations are good for books but less so in practice.
Several resources that I have looked at:
https://www.agner.org/optimize/#testp
Great suite of several books
www.youtube.com/watch?v=WDIkqP4JbkE&t
Scott Meyers talk on memory
https://people.freebsd.org/~lstewart/articles/cpumemory.pdf
On memory
www.youtube.com/watch?v=rX0ItVEVjHc&t
Data-oriented programming
https://www.dataorienteddesign.com/dodbook/
data oriented design book
There are also other resources but it already gives you an idea on what I'm basing
No, real programs are not written like that. Real programs are written by noticing that all the monsters have a bunch of things in common, and using the same code to do those things. They all pathfind, but they have different distances they can walk? Great. Add a max_walking_distance variable and call the same function each time.
All your monsters have a 3D model? Then you don't need a virtual render method. You can just render the model.
You don't have to divide up your data according to "sensible" boundaries. You don't have to have a struct monster. You can have a struct monster_pathfinding and a struct monster_position and a struct monster_3d_model. Even if you just put these in parallel arrays (i.e. monster 123 has its pathfinding info in monsters_pathfinding[123] and its position in monster_positions[123]) this can make more efficient use of the data cache, because the pathfinding code doesn't load the 3D model pointers into the cache. You can get cleverer by skipping entries if some monsters don't pathfind or don't render. Essentially it is recommended for performance that you group data together according to how it's used, not according to your mental model of the things in the game. Yes, skipping entries makes it way more difficult to delete monsters. But you tick monsters a lot, and you don't delete monsters very often, right?
Maybe only a few monsters shoot guns at the player (the rest try to eat the player). You can have a struct monster_gun_data {int ammunition; int max_ammunition; int reload_time; monster_position *position;}; and then if you have 200 monsters, but only 10 of them have guns, your monstersShootGunsAtPlayers function only has to iterate over the 10 entries in the monster_gun_data array (and load their positions via pointers). Or, you might profile that and find out that because most monsters in your game have guns, it's slightly faster to iterate over all the monsters and check their MONSTER_HAS_GUN flag instead, than to access the position through a pointer which can't be prefetched as easily.
How do you do different kinds of monster attacks? Well, if they're completely different (melee vs ranged), you probably do them with different functions as you have described. Or you might only check the attack type after you decide the monster wants to attack the player. You seem to suggest monsters use different attack code, but I bet this works for almost all of them:
if(wantsToAttack(monster, player)) {
if((monster->flags & HAS_RANGED_ATTACK) && distance(monster, player) > monster->melee_attack_distance)
startRangedAttack(monster, player);
else
startMeleeAttack(monster, player);
}
And what's really different between a monster with a gun, and a monster with a bow and arrow? The attack speed, the animation, the speed the projectile moves at, the projectile's 3D model, and the amount of damage it does. That's all data. That isn't different code.
Finally, if you have something completely different, you might consider making it a "strategy object" with a virtual function. Or just a plain function pointer, if you can. Note that the Monster object is still not polymorphic, because if it was, we couldn't have an array of them and that would slow down all the common code. Only the specific parts of the monster that we're saying are polymorphic are actually polymorphic.
void SpecialBossTickFunction(Monster *monster) {
// special movement, etc
}
// ...
monster->onTick = &SpecialBossTickFunction;
// monster is still not polymorphic except for this one field
You could also do:
struct SpecialBossTickStrategy : TickStrategy {
void onTick(Monster *monster) override {...}
// then you can also have extra fields if needed
// but you also have more indirection
};
monster->onTick = new SpecialBossTickStrategy;
And don't do stuff unnecessarily. Try to be event-driven instead of doing stuff every tick:
// bad because we're calling this function unnecessarily every tick
void SpecialUndeadMonsterTickFunction(Monster *monster) {
if(monster->isDead) {
// do some special reanimation sequence
}
}
monster->onTick = &SpecialUndeadMonsterTickFunction;
// better (for performance)
void SpecialUndeadMonsterTickWhileDeadFunction(Monster *monster) {
// do some special reanimation sequence
if (finished doing whatever) {
monster->onTick = NULL;
}
}
void SpecialUndeadMonsterDeathFunction(Monster *monster) {
monster->onTick = &SpecialUndeadMonsterTickWhileDeadFunction;
}
// ...
monster->onDead = &SpecialUndeadMonsterDeathFunction;
// Also better (for performance)
void DoUndeadMonsterReanimationSequences() { // not virtual at all, called from the main loop
for(Monster *monster : special_undead_monsters_which_are_currently_dead) {
// do some special reanimation sequence
}
}
// Not great, but perhaps still less bad than the first one!
void DoUndeadMonsterReanimationSequences() { // not virtual at all, called from the main loop
for(Monster &monster : all_monsters) {
if(monster.type == TYPE_SPECIAL_UNDEAD_MONSTER && monster.isDead) {
// do some special reanimation sequence
}
}
}
Note that in the third example you have to keep this array special_undead_monsters_which_are_currently_dead up to date. That's okay, because you only have to change it when a monster spawns, disappears, dies, or un-dies. And those are relatively rare events. You are doing a bit more work in these events, in order to save work every tick.
Finally, keep in mind these are techniques that may or may not improve performance in your actual program. I see DOD as a grab-bag of ideas. It doesn't say you must write your program in exactly a certain way, but it is offering a bunch of unconventional suggestions, the theory to explain why they work, and examples of how other people have managed to use them in their programs. Since DOD usually suggests that you complete reorganize your data structures, you may only want to implement it in the performance-critical areas of your program.
Just to add some more perspective on the top-level question:
Big projects that require very good performance really don't use polymorphism?
You're missing out an entire category of polymorphism.
I often mix all three of the below styles in a project, because not all code has the same performance requirements:
setup and configuration code doesn't generally need to be (very) fast. Use OO style and runtime polymorphism all you want for properties, factories, whatever.
Runtime polymorphism broadly means virtual functions.
steady-state code that does need to be fast can often use compile-time polymorphism. This works well for a statically-known (and ideally small) collection of types with similar interfaces.
Compile-time polymorphism means templates (function templates, type templates, replacing the run-time Strategy pattern with the equivalent Policy, etc.)
the code with the tightest performance requirements may need to be data-oriented (ie, designed around cache friendliness).
This isn't all the code in the project, and probably isn't even all the code that needs to be fast. It's all the code that needs to be fast and where performance is dominated by cache effects.
If you only have one copy of an object, you may well inline as much as possible (and try to fit it into the fewest cache lines possible), but splitting it into four different arrays with only one element each won't achieve much.

Text Adventure Game - How to Tell One Item Type from Another and How to Structure the Item Classes/Subclasses?

I'm a beginner programmer (who has a bunch of design-related scripting experience for video games but very little programming experience - so just basic stuff like loops, flow control, etc. - although I do have a C++ fundamentals and C++ data structures and algorithm's course under my belt). I'm working on a text-adventure personal project (I actually already wrote it in Python ages ago before I learned how classes work - everything is a dictionary - so it's shameful). I'm "remaking" it in C++ with classes to get out of the rut of having only done homework assignments.
I've written my player and room classes (which were simple since I only need one class for each). I'm onto item classes (an item being anything in a room, such as a torch, a fire, a sign, a container, etc.). I'm unsure how to approach the item base class and derived classes. Here are the problems I'm having.
How do I tell whether an item is of a certain type in a non-shit way (there's a good chance I'm overthinking this)?
For example, I set up my print room info function so that in addition to whatever else it might do, it prints the name of every object in its inventory (i.e. inside of it) and I want it to print something special for a container object (the contents of its inventory for example).
The first part's easy because every item has a name since the name attribute is part of the base item class. The container has an inventory though, which is an attribute unique to the container subclass.
It's my understanding that it's bad form to execute conditional logic based on the object's class type (because one's classes should be polymorphic) and I'm assuming (perhaps incorrectly) that it'd be weird and wrong to put a getHasInventory accessor virtual function in the item base class (my assumption here is based on thinking it'd be crazy to put virtual functions for every derived class in the base class - I have about a dozen derived classes - a couple of which are derived classes of derived classes).
If that's all correct, what's an acceptable way to do this? One obvious thing is to add an itemType attribute to the base and then do conditional logic but this strikes me as wrong since it seems to just be a re-skinning of the checking class type solution. I'm unsure whether the above-mentioned assumptions are correct and what a good solution might be.
How should I structure my base class/classes and my derived classes?
I originally wrote them such that the item class was the base class and most other classes used single inheritance (except for a couple which had multi-level).
This seemed to present some awkwardness and repeating myself though. For example, I want a sign and a letter. A sign is a Readable Item > Untakeable Item > Item. A letter is a Readable Item > Takeable Item > Item. Because they all use single inheritance I need two different Readable Items, one that's takeable and one that's not (I know I could just make takeable and untakeable into attributes of the base in this instance and I did but this works as an example because I still have similar issues with other classes).
That seems icky to me so I took another stab at it and implemented them all using multiple inheritance & virtual inheritance. In my case that seems more flexible because I can compose classes of multiple classes and create a kind of component system for my classes.
Is one of these ways better than the other? Is there some third way that's better?
One possible way to solve your problem is polymorphism. By using polymorphism you can (for example) have a single describe function which when invoked leads the item to describe itself to the player. You can do the same for use, and other common verbs.
Another way is to implement a more advanced input parser, which can recognize objects and pass on the verbs to some (polymorphic) function of the items for themselves to handle. For example each item could have a function returning a list of available verbs, together with a function returning a list of "names" for the items:
struct item
{
// Return a list of verbs this item reacts to
virtual std::vector<std::string> get_verbs() = 0;
// Return a list of name aliases for this item
virtual std::vector<std::string> get_names() = 0;
// Describe this items to the player
virtual void describe(player*) = 0;
// Perform a specific verb, input is the full input line
virtual void perform_verb(std::string verb, std::string input) = 0;
};
class base_torch : public item
{
public:
std::vector<std::string> get_verbs() override
{
return { "light", "extinguish" };
}
// Return true if the torch is lit, false otherwise
bool is_lit();
void perform_verb(std::string verb, std::string) override
{
if (verb == "light")
{
// TODO: Make the torch "lit"
}
else
{
// TODO: Make the torch "extinguished"
}
}
};
class long_brown_torch : public base_torch
{
std::vector<std::string> get_names() override
{
return { "long brown torch", "long torch", "brown torch", "torch" };
}
void describe(player* p) override
{
p->write("This is a long brown torch.");
if (is_lit())
p->write("The torch is burning.");
}
};
Then if the player input e.g. light brown torch the parser looks through all available items (the ones in the players inventory followed by the items in the room), get each items name-list (call the items get_names() function) and compare it to the brown torch. If a match is found the parser calls the items perform_verb function passing the appropriate arguments (item->perform_verb("light", "light brown torch")).
You can even modify the parser (and the items) to handle adjectives separately, or even articles like the, or save the last used item so it can be referenced by using it.
Constructing the different rooms and items is tedious but still trivial once a good design has been made (and you really should spend some time creating requirement, analysis of the requirements, and creating a design). The really hard part is writing a decent parser.
Note that this is only two possible ways to handle items and verbs in such a game. There are many other ways, to many to list them all.
You are asking some excellent questions reg. how to design, structure and implement the program, as well as how to model the problem domain.
OOP, 'methods' and approaches
The questions you ask indicate that you have learned about OOP (object-oriented programming). In a lot of introductory material on OOP, it is common to encourage modelling the problem domain directly through objects and subtyping and implementing functionality by adding methods to them. A classical example is modelling animals, with for instance an Animal type and two sub-types, Duck and Cat, and implementing functionality, for instance walk, quack and mew.
Modelling the problem domain directly with objects and subtyping can make sense, but it can also very much be overkill and bothersome compared to simply having a single or a few types with different fields describing what it is. In your case, I do believe a more complex modelling like you have with objects and subtypes or alternative approaches can make sense, since among other aspects you have functionality that varies depending on the type as well as somewhat complex data (like a container with an inventory). But it is something to keep in mind - there are different trade-offs, and sometimes, having a single type with multiple different fields for modelling the domain can make more sense overall.
Implementing the desired functionality through methods on a base class and subtypes likewise have different trade-offs, and it is not always a good approach for the given case. For one of your questions, you could do something like adding a print method or similar to the base type and each subtype, but this is not always that nice in practice (a simple example is that of a calculator application where simplifying the arithmetic expression the user enters (like (3*x)*4/2) might be bothersome to implement if one uses the approach of adding methods to the base class).
Alternative approach - Tagged unions/sum types
There is a very nice fundamental abstraction known as "tagged union" (it is also known by the names "disjoint union" and "sum type"). The main idea about the tagged union is that you have a union of several different sets of instances, where which set the given instance belongs to matters. They are a superset of the feature in C++ known as enum. Regrettably, C++ does not currently support tagged unions, though there are research into it (for instance https://www.stroustrup.com/OpenPatternMatching.pdf , though this may be somewhat beyond you if you are a beginner programmer). As far as I can see, this fits very well with the example you have given here. An example in Scala would be (many other languages support tagged unions as well, such as Rust, Kotlin, Typescript, the ML-languages, Haskell, etc.):
sealed trait Item {
val name: String
}
case class Book(val name: String) extends Item
case object Fire extends Item {
val name = "Fire"
}
case class Container(val name: String, val inventory: List[Item]) extends Item
This describes your different kinds of items very well as far as I can see. Do note that Scala is a bit special in this regard, since it implements tagged unions through subtyping.
If you then wanted to implement some print functionality, you could then use "pattern matching" to match which item you have and do functionality specific to that item. In languages that support pattern matching, this is convenient and non-fragile, since the pattern matching checks that you have covered each possible case (similar to switch in C++ over enums checking that you have covered each possible case). For instance in Scala:
def getDescription(item: Item): String = {
item match {
case Book(_) | Fire => item.name
case Container(name, inventory) =>
name + " contains: (" +
inventory
.map(getDescription(_))
.mkString(", ") +
")"
}
}
val description = getDescription(
Container("Bag", List(Book("On Spelunking"), Fire))
)
println(description)
You can copy-paste the two snippets in here and try to run them: https://scalafiddle.io/ .
This kind of modelling works very well with what one might call "data types", where you have no or very little functionality in the classes themselves, and where the fields inside the classes basically are part of their interface ("interface" in the sense that you would like to change the implementations that uses the types if you ever add to, remove or change the fields of the types).
Conversely, I find a more conventional subtyping modelling and approach more convenient when the implementation inside of a class is not part of its interface, for instance if I have a base type that describes a collision system interface, and each of its subtypes have different performance characteristics, handy for different situations. Hiding and protecting the implementation since it is not part of the interface makes a lot of sense and fits very well with what one might call "mini-modules".
In C++ (and C), sometimes people do use tagged unions despite the lack of language support, in various ways. One way that I have seen being used in C is to make a C union (though do be careful reg. aspects such as memory and semantics) where an enum tag was used to differentiate between the different cases. This is error-prone, since you might easily end up accessing a field in one enum case that is not valid for that enum case.
You could also model your command input as a tagged union. That said, parsing can be somewhat challenging, and parsing libraries may be a bit involved if you are a beginner programmer; keeping the parsing somewhat simple might be a good idea.
Side-notes
C++ is a special languages - I do not quite like it for cases where I do not care much about resource usage or runtime performance and the like for multiple different reasons, since it can be annoying and not that flexible to develop in. And it can be challenging to develop in, because you must always take great care to avoid undefined behaviour. That said, if resource usage or runtime performance do matter, C++ can, depending on case, be a very good option. There are also a number of very useful and important insights in the C++ language and its community, such as RAII, ownership and lifetimes. My recommendation is that learning C++ is a good idea, but that you should also learn other languages, maybe for instance a statically-typed functional programming language. FP (functional programming) and languages supporting FP, has a number of advantages and drawbacks, but some of their advantages are very, very nice, especially reg. immutability as well as side-effects.
Of these languages, Rust may be the closest to C++ in certain regards, though I don't have experience with Rust and cannot therefore vouch for either the language or its community.
As a side-note, you may be interested in this Wikipedia-page: https://en.wikipedia.org/wiki/Expression_problem .

List design (Object oriented) suggestion needed

I'm trying to implement a generic class for lists for an embedded device using C++. Such a class will provide methods to update the list, sort the list, filter the list based on some user specified criteria, group the list based on some user specified criteria etc. But there are quite a few varieties of lists I want this generic class to support and each of these varieties can have different display aspects. Example: One variety of list can have strings and floating point numbers in each of its elements. Other variety could have a bitmap, string and special character in each of it's elements. etc.
I wrote down a class with the methods of interest (sort, group, etc). This class has an object of another class (say DisplayAspect) as its member. But the number of member variables and the type of each member variable of class DisplayAspect is unknown. What would be a better way to implement this?
Why not use the std::list, C++ provides that and it provides all the functionality you mentioned(It is templated class, So it supports all data types you can think of).
Also, there is no point reinventing the wheel as the code you write will almost will never be as efficient as std::list.
In case you still want to reinvent this wheel, You should write a template list class.
First, you should probably use std::list as your list, as others have stated. It seems to me that you are having problems more with what to put in the list, however, so I'm focusing on that part of the question.
Since you want to also store multiple bits of information in each element of the list, you will need to create multiple classes, one to store each combination. You don't describe why you are storing mutiple bits of information, but you'd want to use a logical name for each class. So if, for example, you were storing a name and a price (string and a double), you could give the class some name like Product.
You mention creating a class called DisplayAspect.
If this is because you want to have one piece of code print all of these lists, then you should use inheritance and polymorphism to accomplish this goal. One way to accomplish that is to make your DisplayAspect class an abstract class with the needed functions (printItem() for example) pure virtual and have each of the classes you created for the combinations of data be subclasses of this DisplayAspect class.
If, on the other hand, you created the DisplayAspect class so that you could reuse your list code, you should look into template classes. std::list is an example of a template class and it will hold any type you'd like to put into it and in that case, you could drop your DisplayAspect class.
Others (e.g., #Als) have already given the obvious, direct, answer to the question you asked. If you really want a linked list, they're undoubtedly correct: std::list is the obvious first choice.
I, however, am going to suggest that you probably don't want a linked list at all. A linked list is only rarely a useful data structure. Given what you've said you want (sorting, grouping), and especially your target (embedded system, so you probably don't have a lot of memory to waste) a linked list probably isn't a very good choice for what you're trying to do. At least right off, it sounds like something closer to an array probably makes a lot more sense.
If you end up (mistakenly) deciding that a linked list really is the right choice, there's a fair chance you only need a singly linked list though. For that, you might want to look at Boost Slist. While it's a little extra work to use (it's intrusive), this will generally have lower overhead, so it's at least not quite a poor of a choice as many generic linked lists.

Shared single variable for list?

This problem is a little difficult to describe, so bear with me if it isn't clear.
I want to implement a doubly-linked list with a single, universally accessible [to the items inside] Head, End and Iter pointers - this would greatly reduce memory overhead and processing/accessing times...
Static almost fulfills this role - except, it's shared by all classes of the same type - which what I don't want [as I might have multiple doubly-linked lists - I need one per list, not one per class]. So what I need is something similar to static, except it's localised to different declarations.
Head/Node methods become complicated (notably as it uses templates) and I want to avoid this at all costs. Head just ends up having duplicate functions of Node [so Node is accessible], which seems a waste and added complexity just to have three local-universal variables.
What I'd like is something similar to this:
class Test
{
private:
static Test *Head; //Single universal declaration!
static Test *End;
static Test *Iter;
//etc etc
};
Except...
Test A; //Set of 'static' variables 'unique' to A
Test B; //Set of 'static' variables 'unique' to B
I am willing to entertain any and all solutions to the problem, but please avoid complicated solutions - this is meant as an improvement and needs to be quick and simple to implement.
Additional Information [as requested]:
There isn't a 'problem' per se [aside in terms of avoiding overhead and design] - this is setting the frame-work/ground-work for several other classes/functions to build on. So the class needs to be able to handle multiple roles/variables/classes - for this, it has to be templated [although this isn't entirely relevant].
One [of many] of it's main roles is storing individual characters [loaded from files] in seperate Nodes. Given the size can vary, it has to be dynamic. However, as one of it's roles involve loading from files, it can't be an array [as reading the file to work out number of arguments, characters etc causes harddrive/access bottlenecks]. So...
...Singly-linked lists would allow a character to be [easily] added [to the list] on each pass that gets a character [and counted at the same time - solving two problems in one]. The problem is singly-linked lists are very hard to [safely] delete, and navigation is one way. Which is a problem as this hinders search functionality, and notably, the intended multipurpose role...
...So the conclusion is it has to be a doubly-linked list. I don't like the STL or standard lists as I have no idea of their efficiency or safety, or indeed, compatibility with additional features the class has to support. So it has to be a custom built D-L-List...
...However I previously (some time ago) implemented a Head/Node method - it worked. However it become complex and difficult to debug as Head and Node shared functions. This time around I just want a simple, single [Readable! It's going to be shared!] class that somehow sidesteps the almost 'beaucratic' nature of C++. That means no Head/Iter/End copying overhead (and all functions/variables/debugging required for it) and no Head system with it's duplication...
...Static is the closest I get. Perhaps there is a way that somehow, you have Class A that stores the three variables, and a Class B that stores the list - and both of them are aware of each other and are able to communicate via some method/function (no pointer storage!)...
...Something along those lines. I am pretty sure there is some hierarchy or sub-class or inheiretence trick that would pull this off, and I need someone who knows the finer arts better than I do to, refine my raw idea or something.
If static variables are not suitable, you have only one possibility - use instance variables.
If you want to share the variables between the items, put them in the list itself and maintain a pointer to the list in each item as follows:
class List
{
Item* head;
Item* end;
Item* iter;
};
class Item
{
List* list;
};
Make a List class (as already shown by vitaut, but add a makeEntry() function in which a reference to the List class can be passed. If List becomes more complicated, I would isolate these members to ListInfo, so the node only have access to them

Are type fields pure evil?

As discusses in The c++ Programming Language 3rd Edition in section 12.2.5, type fields tend to create code that is less versatile, error-prone, less intuitive, and less maintainable than the equivalent code that uses virtual functions and polymorphism.
As a short example, here is how a type field would be used:
void print(const Shape &s)
{
switch(s.type)
{
case Shape::TRIANGE:
cout << "Triangle" << endl;
case Shape::SQUARE:
cout << "Square" << endl;
default:
cout << "None" << endl;
}
}
Clearly, this is a nightmare as adding a new type of shape to this and a dozen similar functions would be error-prone and taxing.
Despite these shortcomings and those described in TC++PL, are there any examples where such an implementation (using a type field) is a better solution than utilizing the language features of virtual functions? Or should this practice be black listed as pure evil?
Realistic examples would be preferred over contrived ones, but I'd still be interested in contrived examples. Also, have you ever seen this in production code (even though virtual functions would have been easier)?
When you "know" you have a very specific, small, constant set of types, it can be easier to hardcode them like this. Of course, constants aren't and variables don't, so at some point you might have to rewrite the whole thing anyway.
This is, more or less, the technique used for discriminated unions in several of Alexandrescu's articles.
For example, if I was implementing a JSON library, I'd know each Value can only be an Object, Array, String, Integer, Boolean, or Null—the spec doesn't allow any others.
A type enum can be serialized via memcpy, a v-table can't. A similar feature is that corruption of a type enum value is easy to handle, corruption of the v-table pointer means instant badness. There's no portable way to even test a v-table pointer for validity, calling dynamic_cast or typeinfo to do RTTI checks on an invalid object is undefined behavior.
For example, one instance where I choose to use a type hierarchy with static dispatch controlled by a discriminator and not dynamic dispatch is when passing a pointer to a structure through a Windows message queue. This gives me some protection against other software that may have allocated broadcast messages from a range I'm using (it's supposed to be reserved for app-local messages, do not pass GO if you think that rule is actually respected).
The following guideline is from Clean Code by Robert C. Martin.
"My general rule for switch statements is that they can be tolerated if they appear only once, are used to create polymorphic objects, and are hidden behind an inheritance relationship so that the rest of the system can't see them".
The rationale is this: if you expose type fields to the rest of your code, you'll get multiple instances of the above switch statement. That is a clear violation of DRY. When you add a type, all these switches need to change (or, even worse, they become inconsistent without breaking your build).
My take is: It depends.
A parameterized Factory Method design pattern relies on this technique.
class Creator {
public:
virtual Product* Create(ProductId);
};
Product* Creator::Create (ProductId id) {
if (id == MINE) return new MyProduct;
if (id == YOURS) return new YourProduct;
// repeat for remaining products...
return 0;
}
So, is this bad. I don't think so as we do not have any other alternative at this stage. This is a place where it is absolutely necessary as it involves creation of an object. The type of the object is yet to be known.
The example in OP is however an example which sure needs refactoring. Here we are already dealing with an existing object/type (passed as argument to function).
As Herb Sutter mentions -
"Switch off: Avoid switching on the
type of an object to customize
behavior. Use templates and virtual
functions to let types (not their
calling code) decide their behavior."
Aren't there costs associated to virtual functions and polymorphism? Like maintaining a vtable per class, increase of each class object size by 4 byptes, runtime slowness (I have never measured it though) for resolving the virtual function appropriately. So, for simple situations, using a type field appears acceptable.
I think that if the type corresponds precisely to the implied classes then type is wrong. Where it gets complicated is where the type does not quite match or its not so cut and dried.
Taking your example what if type was Red, Green, Blue. Those are types of shapes. You could even have a color class as a mixin; but its probably too much.
I am thinking of using a type field to solve the problem of vector slicing. That is, I want a vector of hierarchical objects. For example I want my vector to be a vector of shapes, but I want to store circles, rectangles, triangles etc.
You can't do that in the most obvious simple way because of slicing. So the normal solution is to have a vector of pointers or smart pointers instead. But I think there are cases where using a type field will be a simpler solution, (avoids new/delete or alternative lifecycle techniques).
The best example I can think of (and the one I've run into before), is when your set of types is fixed and the set of functions you want to do (that depend on those types) is fluid. That way, when you add a new function, you modify a single place (adding a single switch) rather than adding a new base virtual function with the real implementation scattered all across the classes in your type hierarchy.
I don't know of any realistic examples. Contrived ones would depend on there being some good reason that virtual methods cannot be used.