Issue with Item System regarding Inheritance - c++

I had a question regarding how to solve the following in C++:
So, say I have 2 items. A Sword, and a Knife.
A sword's structure looks like the following:
baseItem > Equippable (Holds events and boolean checks) > Weapon (Same) > Sword
A knife's structure looks like the following:
baseItem > Equippable > Weapon > Knife
Most of my classes and functions that will be dealing with items (Inventory, Containers, the function that creates the Item Instances) will all be of type baseItem.
How do I specify functions such as:
baseItem createItem(int index, type itemType)
in such a way that I can return or cast back up to Sword/Knife? This is especially a concern with inventories as I will need to pull items from ItemSlot which will also hold objects of type baseItem, but will need to constantly check if they are Sword, Knife, etc.

You can do it with a template member function, like this:
class baseItem {
... // Private members
public:
template <typename T> static T* createItem(int index);
};
Then you will be able to call this with the exact type in a type parameter, like this:
Sword *sword = basrItem::createItem<Sword>(123);
Demo on ideone.
A couple of notes:
You need to return by pointer, regular or "smart", to avoid object slicing.
You may want to move the createItem member to a separate "factory" / "registry" class
If you keep a registry, you need to be careful about the ownership of your objects (i.e. avoid deleting them when they are inside the registry, or when they go out of registry while being in use elsewhere).
To illustrate the last point, here is what I mean by a registry class:
class baseItemRegistry {
map<int,unique_ptr<baseItem> > registry;
public:
template <typename T> static T* createItem(int index) {
map<int,baseItem*>::const_iterator iter = registry.find(index);
if (iter != registry.end()) {
return dynamic_cast<T*>(iter->second);
}
T* res = new T(index);
registry[index] = res;
return res;
}
};
This would let you keep a baseItemRegistry object that you can decide to share, but you could also hide it it you need a "private" registry. static functions do not give you this flexibility.

You use dynamic cast to cast to the derived type and check whether it is of that type. If you return the type by value you run into the slicing problem: What is object slicing?

You could return a pointer (preferably wrapped up in some kind of smart pointer) e.g. shared_ptr:
std::shared_ptr<baseItem> createItem(int index, type itemType)
{
// Your logic
return std::shared_ptr<baseItem>(new Sword()); // or whatever
} // eo createItem
And later on your cast to the appropriate type using dynamic_cast.

Generally you may cast baseItem to knife or sword with dynamic_cast, but that's not a good practice. Basically all behavior that depends on type of object should be located in the virtual member-functions of your classes.

Related

Automatic Return Type for Pointers in C++

I hope the headline isn't too confusing. What I have is a class StorageManager containing a list of objects of classes derived from Storage. Here is an example.
struct Storage {}; // abstract
class StorageManager
{
private:
map<string, unique_ptr<Storage>> List; // store all types of storage
public:
template <typename T>
void Add(string Name) // add new storage with name
{
List.insert(make_pair(Name, unique_ptr<Storage>(new T())));
}
Storage* Get(string Name) // get storage by name
{
return List[Name].get();
}
};
Say Position is a special storage type.
struct Position : public Storage
{
int X;
int Y;
};
Thanks to the great answers on my last question the Add function already works. What I want to improve is the Get function. It reasonable returns a pointer Storage* what I can use like the following.
int main()
{
StorageManager Manager;
Manager.Add<Position>("pos"); // add a new storage of type position
auto Strge = Manager.Get("pos"); // get pointer to base class storage
auto Pstn = (Position*)Strge; // convert pointer to derived class position
Pstn->X = 5;
Pstn->Y = 42;
}
It there a way to get rid of this pointer casting by automatically returning a pointer to the derived class? Maybe using templates?
use:
template< class T >
T* Get(std::string const& name)
{
auto i = List.find(name);
return i == List.end() ? nullptr : static_cast<T*>(i->second.get());
}
And then in your code:
Position* p = Manager.Get<Position>("pos");
I don't see what you can do for your Get member function besides what #BigBoss already pointed out, but you can improve your Add member to return the used storage.
template <typename T>
T* Add(string Name) // add new storage with name
{
T* t = new T();
List.insert(make_pair(Name, unique_ptr<Storage>(t)));
return t;
}
// create the pointer directly in a unique_ptr
template <typename T>
T* Add(string Name) // add new storage with name
{
std::unique_ptr<T> x{new T{}};
T* t = x.get();
List.insert(make_pair(Name, std::move(x)));
return t;
}
EDIT The temporary prevents us from having to dynamic_cast.
EDIT2 Implement MatthieuM's suggestion.
You can also further improve the function by accepting a value of the
type to be inserted, with a default argument, but that might incur an
additional copy.
When you have a pointer or reference to an object of some class, all you know is that the actual runtime object it references is either of that class or of some derived class. auto cannot know the runtime type of an object at compile time, because the piece of code containing the auto variable could be in a function that is run twice -- once handling an object of one runtime type, another handling an object with a different runtime type! The type system can't tell you what exact types are in play in a language with polymorphism -- it can only provide some constraints.
If you know that the runtime type of an object is some particular derived class (as in your example), you can (and must) use a cast. (It's considered preferable to use a cast of the form static_cast<Position*>, since casts are dangerous, and this makes it easier to search for casts in your code.)
But generally speaking, doing this a lot is a sign of poor design. The purpose of declaring a base class and deriving other class types from it is to enable objects of all of these those types to be treated the same way, without casting to a particular type.
If you want to always have the correct derived type at compile time without ever using casts, you have no choice but to use a separate collection of that type. In this case, there is probably no point deriving Position from Storage.
If you can rearrange things so that everything that a caller of StorageManager::Get() needs to do with a Position can be done by calling functions that don't specify Position-specific information (such as co-ordinates), you can make these functions into virtual functions in Storage, and implement Position-specific versions of them in Position. For example, you could make a function Storage::Dump() which writes its object to stdout. Position::Dump() would output X and Y, while the implementations of Dump() for other conceivable derived classes would output different information.
Sometimes you need to be able to work with an object that could be one of several essentially unrelated types. I suspect that may be the case here. In that case, boost::variant<> is a good way to go. This library provides a powerful mechanism called the Visitor pattern, which allows you to specify what action should be taken for each of the types that a variant object could possibly be.
Apart from the fact that this looks like a terrible idea... let's see what we can do to improve the situation.
=> It's a bad idea to require default construction
template <typename T>
T& add(std::string const& name, std::unique_ptr<T> element) {
T& t = *element;
auto result = map.insert(std::make_pair(name, std::move(element)));
if (result.second == false) {
// FIXME: somehow add the name here, for easier diagnosis
throw std::runtime_error("Duplicate element");
}
return t;
}
=> It's a bad idea to downcast blindly
template <typename T>
T* get(std::string const& name) const {
auto it = map.find(name);
return it != map.end() ? dynamic_cast<T*>(it->second.get()) : nullptr;
}
But frankly, this system is quite full of holes. And probably unnecessary in the first place. I encourage you to review the general problem an come up with a much better design.

Dynamic mapping of enum value (int) to type

It appeared that this problem is quite common in our job.
We we are sending an int or enum value through the network, then we receive it we would like to create/call a particular object/function.
The most simply solution would be to use the switch statement, like below:
switch (value) {
case FANCY_TYPE_VALUE: return new FancyType();
}
It works fine, but we would have plenty of these switch blocks, and when we create new value and type, we would need to change all of them. It does seem right.
Other possibility would be to use the templates. But we cannot, since the value of enum is defined in runtime.
Is there any right design pattern for that, or any right approach?
It seems like a very general and common problem in every day coding...
Try a map:
struct Base { };
struct Der1 : Base { static Base * create() { return new Der1; } };
struct Der2 : Base { static Base * create() { return new Der2; } };
struct Der3 : Base { static Base * create() { return new Der3; } };
std::map<int, Base * (*)()> creators;
creators[12] = &Der1::create;
creators[29] = &Der2::create;
creators[85] = &Der3::create;
Base * p = creators[get_id_from_network()]();
(This is of course really crude; at the very least you'd have error checking, and a per-class self-registration scheme so you can't forget to register a class.)
You can actually do this with some template trickery:
#include <map>
template <typename Enum, typename Base>
class EnumFactory {
public:
static Base* create(Enum e) {
typename std::map<Enum,EnumFactory<Enum,Base>*>::const_iterator const it = lookup().find(e);
if (it == lookup().end())
return 0;
return it->second->create();
}
protected:
static std::map<Enum,EnumFactory<Enum,Base>*>& lookup() {
static std::map<Enum,EnumFactory<Enum,Base>*> l;
return l;
}
private:
virtual Base* create() = 0;
};
template <typename Enum, typename Base, typename Der>
class EnumFactoryImpl : public EnumFactory<Enum,Base> {
public:
EnumFactoryImpl(Enum key)
: position(this->lookup().insert(std::make_pair<Enum,EnumFactory<Enum,Base>*>(key,this)).first) {
}
~EnumFactoryImpl() {
this->lookup().erase(position);
}
private:
virtual Base* create() {
return new Der();
}
typename std::map<Enum,EnumFactory<Enum,Base>*>::iterator position;
};
This allows you to create a new derived object from a given enum, by saying
// will create a new `FancyType` object if `value` evaluates to `FANCY_TYPE_VALUE` at runtime
EnumFactory<MyEnum,MyBase>::create(value)
However, you have to have some EnumFactoryImpl objects, which could be static in some function or namespace.
namespace {
EnumFactoryImpl<MyEnum,MyBase,Derived1> const fi1(ENUM_VALUE_1);
EnumFactoryImpl<MyEnum,MyBase,Derived2> const fi2(ENUM_VALUE_2);
EnumFactoryImpl<MyEnum,MyBase,Derived3> const fi3(ENUM_VALUE_3);
EnumFactoryImpl<MyEnum,MyBase,FancyType> const fi1(FANCY_TYPE_VALUE); // your example
}
These lines are the single point where your source code maps enum values to derived types. So you have everything at the same location, and no redundancy (this eliminates the problem of forgetting to change it in some places, when adding new derived types).
One option is to maintain a dictionary of creators(which has the same interface) that can create a concrete type. Now the creation code will search in the dictionary for an int value (resulting from the enum sent from the client) and call the create method, which returns the concrete object via a base-class pointer.
The dictionary can be initialized at one place with the concrete creators corresponding to each possible enum values.
The problem here is that you have to extend this dictionary initialization code when you add a new type of object. A way to avoid is as following.
Let the creator look for a singleton factory instance and register itself in the constructor with the type enums(integers) with which it can create a concret object.
Create a DLL for one/set of creators and have a global instance of the creators.
The name of the DLL can be entered in a config file which is read by the factory in the initialization. The factory loads all the DLLs in this file and this results in the creation of the static objects which registers themselves with the factory.
Now the factory has the map of all the type enums which it can create with the concrete object creators.
The same object creator look-up mechanism is implemented to create the objects.
Now, the factory doesn't need to be extended at all since step 3,4 and 5 doesn't change for new objects introduced. Step 1 can be implemented in one place.
Only thing you need to do is to add a global object for each of the new concrete type which should be there since the C++ doesn't support reflection natively.
kogut, I don't propose this as an answer, but since you ask me to expand on my comment on your original question here's a very brief summary of what the .net environment gives you...
public enum MyEnum
{
[MyAttribute(typeof(ClassNone))]
None,
[MyAttribute(typeof(ClassOne))]
One,
[MyAttribute(typeof(ClassTwo))]
Two,
[MyAttribute(typeof(ClassThree))]
Three
}
So you have your basic enum One, Two, Three etc. which works just like....er....an enum!
But you also code up a class called MyAttribute (and in fact for more information in this area, just search for Attributes). But as you can see this allows you to say, at design time, that such-and-such an enum value is associated with such-and-such a class.
This information is stored in the enum's metadata (the value of a managed environment!) and can be interrogated at runtime (using Reflection). Needless to say this is very powerful, I've used this mechanism to systematically strip out loads of maps of the kind proposed in other answers to your question.
An example of the usefulness is this...at one client I worked with, the convention was to store statuses as strings in a database on the grounds that they would be more readable to a human who needed to run a table query. But this made no sense in the applications, where statuses were pushed through as enums. Take the above approach (with a string rather than a type) and this transform happened on a single line of code as data was read and written. Plus, of course, once you've defined MyAttribute it can be tagged onto any enum you like.
My language if choice these days is c# but this would also be good in (managed) c++.

variable return type in c++ class

i have a class with the following structure:
class myClass
{
private:
int type;
classOne objectOne;
classTwo objectTwo;
public:
myClass(classOne object)
{
this->objectOne = object;
this->type = 0;
}
myClass(classTwo object)
{
this->objectTwo = object;
this->type = 1;
}
}
i now want a method returning an object of type classOne if type is 0 and of type classTwo if type is 1. I do not want two methods to achieve this. the classes have different structures.
Is this even possible? Any suggestions are appreciated :)
You can use Boost.Variant to do this. A variant can be constructed directly from any value convertible to one of its bounded types. Similarly, a variant can be assigned any value convertible to one of its bounded types. Heres how you could use it in your class:
class myClass
{
private:
boost::variant<classOne, classTwo> obj;
public:
myClass(classOne object) : obj(object)
{
}
myClass(classTwo object) : obj(object)
{
}
};
It also provides a very convenient boost::get to retrieve the value from the variant.
You can use that to supply code for each bounded type you have(ie classOne and classTwo). Here is an example:
if (classOne * x = boost::get<classOne>(&obj))
{
//Code for classOne
}
else if (classTwo * x = boost::get<classTwo>(&obj)
{
//Code for classTwo
}
However, such code is quite brittle, and without careful attention will likely lead to the introduction of subtle logical errors detectable only at runtime. Thus, real-world use of variant typically demands an access mechanism more robust than get. For this reason, variant supports compile-time checked visitation via apply_visitor. Visitation requires that the programmer explicitly handle (or ignore) each bounded type. Failure to do so results in a compile-time error.
Visitation of a variant requires a visitor object. Like this:
class object_visitor
: public boost::static_visitor<>
{
public:
void operator()(classOne & x) const
{
//Code for classOne
}
void operator()(classTwo & x) const
{
//Code for classTwo
}
};
With the implementation of the above visitor, we can then apply it to obj, as seen in the following:
boost::apply_visitor( object_visitor(), obj );
Unless the two types are related (in which case you can create a function that will return a pointer/reference to the common ancestor) you cannot do that directly in C++.
C++ is a statically typed language, meaning that the type of every expression must be known at compile time, but you are trying to define a function whose return type depends on runtime values.
Depending on the particular problem to solve, there might be different approaches that you could take, including using type erasure (return a boost::any, boost::variant or your own type-erasure).
ClassOne and ClassTwo need to have the same return type then either via inheritance or composition. i.e ClassOne and ClassTwo need to be subclasses of the same super class OR they need to impl the same interface.
I am not sure why you would not use templates for your case.
You can have something like below:
template <class ClassType>
class myClass
{
private:
int type;
ClassType object;
public:
myClass(ClassType object_in)
{
this->object = object_in;
/*
C++ doesn't support reflection so I don't think there
is a robust way of doing the following at runtime.
*/
type = /* Get Type at runtime */;
}
/*
Have another method which return object in a straigtforward way.
*/
};
However, then this become trivial. Any more insight into what your use case is, such that you have to know the type?
Update:
If the ClassType is going to be an Object, you can have a const static int TypeID member for the class, which is set at compile time. You can then use it determine the Type at runtime.
If they're completely different structures, with no common base then an alternative way you can return them from the same function is to use void*.
However that's bad form in C++, usually indicating a design failure - either use two different functions, or use a common base class.
It's apples and oranges. If you put an apple into an recipe that calls for an orange it won't be the same recipe anymore.
The use of type-id is a sign that you need virtual functions for myClass. Even if the other two classes are totally independent, the fact that they are returned by the same function could easily make them inherit a base class. And also you can just return a pair containing class1, class2 and one of them can be null.
The first problem is how you will determine the class of which type has been returned. I think it is possible to return a pointer to structure of this type
struct res {
myClass* c1;
ClassOne* c2;
} ;
The field of the not chosen class is NULL, the other points to the object.

C++ Templated return

I have a program which is built on "Entities", which hold "Components" (composition FTW).
Components may include many different types including scripts, assets, etc. I would like to build an Entity function called
Entities have a map of strings, and actual Components, such that the Components can be searched for by type name.
I would like to have a function called
<Component T>GetComponent(char* TypeName, <T>);
Which takes in a string and a type name, and which returns the typed component that is requested.
Is it possible to do such a thing with C++ templates? The above clearly does not work, and I'm not sure how to go about it.
Thanks
Edit:
I'm not looking for a factory.
Entity holds instances of different types of components. Currently this is done with
std::vector<Component> componentList;
and an
std::vector<char*> componentNames;
Whose indexes are guaranteed to be the same. Likely I will write a proper map later.
I simply want GetComponent to return a properly typed reference to the already instantied component of type name held by Entity in the ComponentList.
Does your function create components? Then it is a factory. You could wrap it in that template in order to save clients the (potentially erroneous) casting.
The type of the function template would look like this:
template< typename T >
T* GetComponent(const char*); // presuming it returns a pointer
and it would be called like this:
Foo* foo = GetComponent<Foo>("foo");
Asking the proper question is at least half of the way to getting a good answer. You should really state what you want to achieve rather than the particular problem you are facing. It seems to me as if you have more problems with the language than you actually realize.
The first part is that it seems as if you have a component hierarchy that derives from Component, probably providing a common interface. An entity holds many components internally, that can be of any derived type from Component. If that is the case, you should rework your containers as you are storing Component objects directly, and that will produce slicing in your objects (no matter what derived type you enter into the container, the container will only keep the common Component part of the object).
Working on a couple of vectors and hoping that both of them will be synchronized at all times is feasible but fragile. If the name and the component go together, then you want to store pairs of name/component. If you want to search by name, you should use a map as it will provide O(log N) search directly.
Now, going back to the question. If what you want to achieve is plain syntactic sugar (avoid the caller from explicitly dynamic casting if needed) then you can get it with a template (more later on). But you should really think on your design. Does Component define the real interface into any component? If users need to downcast to particular types before using a Component, either the abstraction is bad (Component does not provide a real interface) or the objects do not really fit together.
If at the end of it you still want to do it, you can hide the dynamic cast from the caller by doing it within a template method (or free function).
class Entity {
typedef std::map< std::string, boost::shared_ptr<Component> > component_map_t;
public:
boost::shared_ptr<Component> getComponent( std::string const & name ) {
component_map_t::iterator it = components_.find(name);
if ( it == components_.end() ) { // not found, handle error
// ...
}
return it->second;
}
template <typename T> // syntactic sugar
boost::shared_ptr<T> getComponent( std::string const & name ) {
return boost::dynamic_pointer_cast<T>( getComponent(name) );
}
private:
component_map_t components_;
};
template <typename T> // syntactic sugar also available as free function
boost::shared_ptr<T> getComponent( Entity & entity, std::string const & name ) {
return boost::dynamic_pointer_cast<T>( entity.getComponent(name) );
}
int main() { // usage
Entity e; // ... work with it add components...
boost::shared_ptr<Component> c1 = e.getComponent( "one" ); // non-templated method returns Component
boost::shared_ptr<DerivedComponent> c2 = e.getComponent<DerivedComponent>( "two" );
boost::shared_ptr<DerivedComponent> c3 = getComponent<DerivedComponent>( e, "two" );
}
You could play with the interface so that instead of boost::shared_ptr you return real references (with what it entails: lifetime must be carefully controlled so that user code does not try to use a dangling reference if the component is removed from the entity).
You could use something like:
struct Entity
{
Component* GetBaseComponent (const char* TypeName)
{
// do lookup on TypeName and return corresponding Component.
}
template<typename T> T* GetComponent (const char* TypeName)
{
return dynamic_cast<T*> (GetBaseComponent (TypeName));
}
};
and call it with something like:
entity.GetComponent<MyComponent> ("MyComponent");
If you ask for a component and get the type wrong the cast will return a null ptr.
Edit: Just realised this is essentially the same solution as sbi, albeit without calling it a factory.
Your getComponent function has two separate tasks
1) retrieve an object from a string identifier
2) cast this object into the provided template argument type
Using templates makes (2) pretty straight forward. But (1) needs work on string objects, so templates won't do the trick on their own. You have got to fill your component container some other way. As for storing and casting, you may be interested in boost::any or boost::variant.

C++ Templates: Coding error or compiler bug?

I'm trying to use templates to get std:list of items, where each item has a pointer to the list which contains it, but I keep hitting a compiler message.
Here's a very stripped down version of the code.
template <class E> class Item
{
public:
E* owner; // pointer to list that owns us.
};
template <class E> class BaseList: public std::list<E>
{
protected:
typedef std::list<E> inherited;
public:
void push_back(const E &e)
{
E tmp(e);
tmp.owner = this; // This line gives the error.
inherited::push_back(tmp);
}
};
class MyList;
class MyItem : public Item<MyList>
{
};
class MyList : public BaseList<MyItem>
{
};
void foo() // test code to instantiate template
{
MyList l;
MyItem m;
l.push_back(m);
}
However, my compiler barfs at the line:-
tmp.owner = this;
Error is:
[BCC32 Error] Unit7.cpp(30): E2034 Cannot convert 'BaseList<MyItem> * const' to 'MyList *'
It's like "this" has somehow become const, but I can't see why. Compiler is Codegear C++Builder 2009.
I admit I'm not 100% happy using templates, so I'm unsure if this is my problem or the compilers. The same code without template use compiles fine, but obviously that's not what I want, as I have several item/list classes that want to work this way.
Also, is there a better technique that would avoid having all the "owner" pointers in each item?
EDIT: I think I stripped the example down too far: "MyList" actually introduces new methods, which "MyItem" must then access through the "owner" pointer.
SUMMARY: Thanks for all comments and answers. As the accepted answer says, the problem is simply one of type incompatibility between pointer to a BaseList vs. MyList.
The issues raised about deriving from STL containers and alternative designs are also helpful, but the solution I've used is essentially identical to Luc Touraille's one below.
At line 30, "this" is a pointer to a BaseList<MyIteM>, not a MyList. You can substitute a class with a derived one, but not the other way around.
You can either typedef MyList to be a BaseList<MyItem>, like so:
typedef BaseList<MyItem> MyList
or let MyItem derive from Item<BaseList<MyItem> > instead.
When you derive from a type, you create a different type. When you typedef, you create an alias for that type. So when you typedef the compiler will accept this.
In addition to the answers you already have, I would also point out that the standard library collection classes are not intended to be derived from, as they do not have virtual destructors, and none of their member functions is virtual.
Shouldn't it be tmp.owner = static_cast<MyList*>(this). The type of E is MyList in the MyItem hence E* will be MyList* . The type of this pointer will be BaseList*, hence compiler gives the error that you can not convert the base class pointer to the derived class pointer.
It's hard to say if there's a better solution, when you don't say what it is you need.
Why do each element need a pointer to the list they're stored in?
Anyway, bad things can happen when you inherit from standard containers. They don't have virtual destructors, so you have to be very careful.
A better solution might be to just provide a free function performing the push_back:
template <typename T>
void push_back(std::list<T>& list, const T& t) {
T tmp(t);
tmp.owner = this;
list.push_back(tmp);
}
Apart from avoiding the nonvirtual destructor problem, it also solves your compiler error, because you now only have one type of list.
Of course, if we know why you need this owner pointer in the first place, better still solutions may exist.
Edit
In response to your edit and the comments, use composition, not inheritance:
struct House {
std::string zipcode;
std::list<Person> persons;
void AddPerson(const Person& person) {
Person tmp(person);
tmp.owner = this; // The owner field should be a house, not the list of persons.
persons.push_back(tmp);
}
};
Although I'm not sold on the almost circular references you get when a House stores a list of Persons, and a Person has a pointer to the House it's in.
I'd prefer to decouple these classes as much as possible. If I want to send a letter to a person, I'd call SendLetter(Person, House). Send a letter to this person in that house.
On the side note, you should not extend any classes from std, they are not built for it.
Specifically they don't have virtual destructor so when you call delete on pointer to base class your derived class's destructor will never get called.
You can read more on it Advice on a better way to extend C++ STL container with user-defined methods
I like jalf's free function idea. I'd make it:
template <class X, class Y> // X must have a push_back(Y) member, Y must have an X* owner member
void push_back(X& container, Y value)
{
value.owner = container;
container.push_back(value);
}
This is agnostic over whether the X passed is
a container itself,
is derived from a container as in the original code
or contains a container and has a forwarding push_back function
As it has already been pointed out, the affectation
tmp.owner = this;
fails because this doesn't have the same type as tmp.owner. One solution is to perform a cast, but to do so, you need to provide the container type to BaseList. This can be done using a typedef in Item. Here is the code:
template <class Item> class BaseList
{
public:
void push_back(Item i)
{
i.owner = static_cast<Item::containerType *>(this); // note the cast
items.push_back(i);
}
Item & back() { return items.back(); }
protected:
std::list<Item> items;
};
template <class Container> class Item
{
public:
typedef Container containerType; // Typedef used by BaseList
containerType* owner; // pointer to list that owns us.
};
I also removed the public derivation of std::list: as many said, this is (most of the time) best avoided ; you should consider using composition, or maybe private inheritance.
P.S.: I tried making owner private and BaseList<Item>::push_back friend of Item, but I didn't manage to do it. Is it possible at all? (If too long to answer in comment, feel free to ask a question and answer it)
Regarding const: The type BaseList<MyItem> * const that the compiler mentions is a red herring -- it's not a pointer-to-a-const-object, but a pointer that is const, i.e. an address that won't change. (When you think about it, this never changes to point to something else, does it?)