I'm trying to create a dynamic array of objects, similar to ArrayLists in Java. I'm new at C++ and can't get it to work.
class Album{
private:
public:
void addPhoto(Photo p){
}
};
What should my private datamember look like and how do I add p to it? And do I need a pointer for some reason?
The functionality you look for already exits in the stl collection classes and and with out knowing you application it would be had to tell you weather you needed a pointer or not.
The basic layout of you underlying container could be something like this.
class Album{
public:
void addPhoto(Photo p){
Photos.push_back(p);
}
private:
std::vector<Photo> Photos;
};
You should use an std::vector.
You could use the built in std::vector class that behaves very similarly to the ArrayList. (edit... looks like someone beat me to it)
#fontanini gave you a good answer, you should use vector if you need a dynamic array of objects.
But maybe you don't need a class to begin with. Not everything in C++ needs to be encapsulated in a class, unless you really need it.
Think about your data structure and what are the requirements. You might want to learn more about standard C++ library and the STL to familiarize yourself with other containers and their capabilities, limitations and objectives:
There are excellent video lectures on STL "Introduction to STL with Stephan T Lavavej"
Related
As everyone knows: It's possbile to create linkes lists with C / C++ in order to make a program dynamical.
But now, I'm programming a "linked Class" in c++.
My Parent-Class "GAME" should have a variable number of Elements. And each Element is a class.
So I programmed this:
class GAME : public LEVEL
{ private:
ELEMENT *startPointer;
public:
GAME()
{ startPointer=NULL;
}
initGame()
{ p=aStartPointer;
while(p!=NULL);//This loop is based on a linked list, so its dynamic
{ startPointer=new ELEMENT(startPointer);
p=p->next;
}
}
}
class ELEMENT
{ private:
ELEMENT *next;
public:
ELEMENT(ELEMENT* nextPointer)
{ next=nextPointer;
}
}
My Problem: I never heard about a linked class before, and I'm not sure if I should use it.
Does professional programmers use such methods (and is it usefull?), or are there better Methods to do this?
are there better Methods to do this?
Yes. Here is one:
class GAME : public LEVEL
{ private:
std::vector<ELEMENT> elements;
...
};
Use the standard library containers:
Generally, use std::vector<>.
If you need uniqueness, use std::set<>
If you need to associate elements with keys, use std::map<>
If you need to insert or delete items from the container very often or very quickly, use std::list<> or std::set<>
There are other considerations. Consult a good book to learn how to effectively use standard containers.
Looks like you are trying to implement a linked list under a different name. A better design would be to use a list or vector as a member of your class to store the ELEMENTS instead of having it be the basic functionality of the GAME class.
This allows you to have a separation between container-like object and your application classes.
If what you're trying to do is create a container that can contain different types of object instances (ie, a non-homogeneous container), there're several approaches (which generally involve homogenizing the container). You can either set up a common base clase so that you can store handles-to-base. Another option is discriminated unions.
As the other posts mention, the container itself should probably be an STL container, unless you have a really good reason to use something else (and even then, the 'more standard', the better; homebrew is not a good idea unless it is for educational purposes only).
I'm attempting to create a generic container type to provide a single common interface, as well as hide the internal containers I'm using as they are subject to change.
Basically I have plugins that return collections of items and I don't wish the plugins to be aware of the type of container my code is using.
Can anyone point me in a better direction then the example code below?
template<class C, typename I>
class Container
{
public:
//...
void push(const I& item)
{
if(typeid(C) == typeid(std::priority_queue<I>))
{
std::priority_queue<I>* container = (std::priority_queue<I>*)&_container;
container->push(item);
}
if(typeid(C) == typeid(std::list<I>))
{
std::list<I>* container = (std::list<I>*)&_container;
container->push_back(item);
}
else
{
//error!
}
};
private:
C _container;
//...
}
Thanks
I have plugins that return collections of items and I don't wish the plugins to be aware of the type of container my code is using.
Have your plugins provide begin and end iterators into their collections of items and then consume the range as you see fit.
The greatest advantage of iterators is that they allow complete decoupling of how the data is stored (the container) from how the data is used (the algorithm; in your case, your application code that consumes the plugin data).
This way, you don't have to care how the plugins store their data and the plugins don't have to care what you do with their data once they give it to you.
You know, when you wrote "common interface", I was sure you were going to show something Java style with an abstract class and subclasses that wrap standard containers. I was surprised to see a bunch of typeid calls...
But then, why do you want to do this? Most containers share a common interface, and with the power of SFINAE, you don't even have to write special code! Just use templates and call the method directly.
EDIT: Forgot that standard containers have no virtual methods and therefore, cannot be dynamic_casted.
Start with a class as above, expose minimal interface needed by your plugins. Then implement it in terms of the container you are going to use. This is called container adapter and it is how std::stack is implemented.
If you really need adapter for more then one STL container go with template, have a look at std::stack, it will show how to do that.
Don't switch on typeid, why would you want that?
BTW, go with what James suggests unless there is a need to expose container itself.
How do I do that? Like you know in Java, you can use an ArrayList and it will take any object as long as you cast it down to whatever it is when you're retrieving the object.
Even better, you can specify what class of objects that ArrayList would store by doing...
new ArrayList()< whateverObject >
I've implemented a linked list data structure in C++ and I'd like to know how I can allow it to do this...
At the moment, I'm just using...
typedef whateverObject ItemType
at the start of my header file for my linked list and then manipulating "ItemType" throughout the implementation of the linked list. So every time I want to change the type, e.g. instead of using the list for storing strings, I want to store an int, I'll have to change the typedef in my linked list's header but I want to be able to simply use it for any object so...
How?!
Thanks.
Templates are the answer to your question.
Define your linked list as follows :
template<typename ItemType>
class ArrayList
{
// What's inside your class definition does not need to be changed
// Include your method definitions here and you'll be fine
};
The type to use is then ArrayList<WhateverObject>.
Use templates. It's a lot to explain so I'll just give you a link where it's explained much better than I'll ever be able to do here: C++ FAQ - Templates.
While you're at it, if you have the time, I suggest you read the whole FAQ, it's really a great resource!
If I have understood well what you ask, templates is what you want.
Take a look here:
http://www.cplusplus.com/doc/tutorial/templates/
In java you can do so, because all classes are inherited from one base class Object. In C++ you do not have it. The reason is that Object base class impose overhead for all objects, while C++ do not like any unnecessary overhead.
If you want to store any object - you can store "void *" data type. The question remained - what you will be able to do with objects, without the knowledge of the type? If you do know - you can cast to the needed type and use it. The practice described above is not safe, and templates are better in most cases.
It looks like I had a fundamental misunderstanding about C++ :<
I like the polymorphic container solution. Thank you SO, for bringing that to my attention :)
So, we have a need to create a relatively generic container type object. It also happens to encapsulate some business related logic. However, we need to store essentially arbitrary data in this container - everything from primitive data types to complex classes.
Thus, one would immediately jump to the idea of a template class and be done with it. However, I have noticed C++ polymorphism and templates do not play well together. Being that there is some complex logic that we are going to have to work, I would rather just stick with either templates OR polymorphism, and not try to fight C++ by making it do both.
Finally, given that I want to do one or the other, I would prefer polymorphism. I find it much easier to represent constraints like "this container contains Comparable types" - a la java.
Bringing me to the topic of question: At the most abstract, I imagine that I could have a "Container" pure virtual interface that has something akin to "push(void* data) and pop(void* data)" (for the record, I am not actually trying to implement a stack).
However, I don't really like void* at the top level, not to mention the signature is going to change every time I want to add a constraint to the type of data a concrete container can work with.
Summarizing: We have relatively complex containers that have various ways to retrieve elements. We want to be able to vary the constraints on the elements that can go into the containers. Elements should work with multiple kinds of containers (so long as they meet the constraints of that particular container).
Edit: I should also mention that the containers themselves need to be polymorphic. That is my primary reason for not wanting to use templated C++.
So - should I drop my love for Java type interfaces and go with templates? Should I use void* and statically cast everything? Or should I go with an empty class definition "Element" that declares nothing and use that as my top level class in the "Element" hierarchy?
One of the reasons why I love stack overflow is that many of the responses provide some interesting insight on other approaches that I hadn't not have even considered. So thank you in advance for your insights and comments.
You can look at using a standard container of boost::any if you are storing truly arbitrary data into the container.
It sounds more like you would rather have something like a boost::ptr_container where anything that can be stored in the container has to derive from some base type, and the container itself can only give you reference's to the base type.
The simple thing is to define an abstract base class called Container, and subclass it for each kind of item you may wish to store. Then you can use any standard collection class (std::vector, std::list, etc.) to store pointers to Container. Keep in mind, that since you would be storing pointers, you would have to handle their allocation/deallocation.
However, the fact that you need a single collection to store objects of such wildly different types is an indication that something may be wrong with the design of your application. It may be better to revisit the business logic before you implement this super-generic container.
Polymorphism and templates do play very well together, if you use them correctly.
Anyway, I understand that you want to store only one type of objects in each container instance. If so, use templates. This will prevent you from storing the wrong object type by mistake.
As for container interfaces: Depending on your design, maybe you'll be able to make them templated, too, and then they'll have methods like void push(T* new_element). Think of what you'll know about the object when you want to add it to a container (of an unknown type). Where will the object come from in the first place? A function that returns void*? Do you know that it'll be Comparable? At least, if all stored object classes are defined in your code, you can make them all inherit from a common ancestor, say, Storable, and use Storable* instead of void*.
Now if you see that objects will always be added to a container by a method like void push(Storable* new_element), then really there will be no added value in making the container a template. But then you'll know it should store Storables.
Can you not have a root Container class that contains elements:
template <typename T>
class Container
{
public:
// You'll likely want to use shared_ptr<T> instead.
virtual void push(T *element) = 0;
virtual T *pop() = 0;
virtual void InvokeSomeMethodOnAllItems() = 0;
};
template <typename T>
class List : public Container<T>
{
iterator begin();
iterator end();
public:
virtual void push(T *element) {...}
virtual T* pop() { ... }
virtual void InvokeSomeMethodOnAllItems()
{
for(iterator currItem = begin(); currItem != end(); ++currItem)
{
T* item = *currItem;
item->SomeMethod();
}
}
};
These containers can then be passed around polymorphically:
class Item
{
public:
virtual void SomeMethod() = 0;
};
class ConcreteItem
{
public:
virtual void SomeMethod()
{
// Do something
}
};
void AddItemToContainer(Container<Item> &container, Item *item)
{
container.push(item);
}
...
List<Item> listInstance;
AddItemToContainer(listInstance, new ConcreteItem());
listInstance.InvokeSomeMethodOnAllItems();
This gives you the Container interface in a type-safe generic way.
If you want to add constraints to the type of elements that can be contained, you can do something like this:
class Item
{
public:
virtual void SomeMethod() = 0;
typedef int CanBeContainedInList;
};
template <typename T>
class List : public Container<T>
{
typedef typename T::CanBeContainedInList ListGuard;
// ... as before
};
First, of all, templates and polymorphism are orthogonal concepts and they do play well together. Next, why do you want a specific data structure? What about the STL or boost data structures (specifically pointer containter) doesn't work for you.
Given your question, it sounds like you would be misusing inheritance in your situation. It's possible to create "constraints" on what goes in your containers, especially if you are using templates. Those constraints can go beyond what your compiler and linker will give you. It's actually more awkward to that sort of thing with inheritance and errors are more likely left for run time.
Using polymorphism, you are basically left with a base class for the container, and derived classes for the data types. The base class/derived classes can have as many virtual functions as you need, in both directions.
Of course, this would mean that you would need to wrap the primitive data types in derived classes as well. If you would reconsider the use of templates overall, this is where I would use the templates. Make one derived class from the base which is a template, and use that for the primitive data types (and others where you don't need any more functionality than is provided by the template).
Don't forget that you might make your life easier by typedefs for each of the templated types -- especially if you later need to turn one of them into a class.
You might also want to check out The Boost Concept Check Library (BCCL) which is designed to provide constraints on the template parameters of templated classes, your containers in this case.
And just to reiterate what others have said, I've never had a problem mixing polymorphism and templates, and I've done some fairly complex stuff with them.
You could not have to give up Java-like interfaces and use templates as well. Josh's suggestion of a generic base template Container would certainly allow you do polymorphically pass Containers and their children around, but additionally you could certainly implement interfaces as abstract classes to be the contained items. There's no reason you couldn't create an abstract IComparable class as you suggested, such that you could have a polymorphic function as follows:
class Whatever
{
void MyPolymorphicMethod(Container<IComparable*> &listOfComparables);
}
This method can now take any child of Container that contains any class implementing IComparable, so it would be extremely flexible.
What's the best way to output the public contents of an object to a human-readable file? I'm looking for a way to do this that would not require me to know of all the members of the class, but rather use the compiler to tell me what members exist, and what their names are. There have to be macros or something like that, right?
Contrived example:
class Container
{
public:
Container::Container() {/*initialize members*/};
int stuff;
int otherStuff;
};
Container myCollection;
I would like to be able to do something to see output along the lines of "myCollection: stuff = value, otherStuff = value".
But then if another member is added to Container,
class Container
{
public:
Container::Container() {/*initialize members*/};
int stuff;
string evenMoreStuff;
int otherStuff;
};
Container myCollection;
This time, the output of this snapshot would be "myCollection: stuff = value, evenMoreStuff=value, otherStuff = value"
Is there a macro that would help me accomplish this? Is this even possible? (Also, I can't modify the Container class.)
Another note: I'm most interested about a potential macros in VS, but other solutions are welcome too.
What you're looking for is "[reflection](http://en.wikipedia.org/wiki/Reflection_(computer_science)#C.2B.2B)".
I found two promising links with a Google search for "C++ reflection":
http://www.garret.ru/cppreflection/docs/reflect.html
http://seal-reflex.web.cern.ch/seal-reflex/index.html
Boost has a serialization library that can serialize into text files. You will, however, not be able to get around with now knowing what members the class contains. You would need reflection, which C++ does not have.
Take a look at this library .
What you need is object serialization or object marshalling. A recurrent thema in stackoverflow.
I'd highly recommend taking a look at Google's Protocol Buffers.
There's unfortunately no macro that can do this for you. What you're looking for is a reflective type library. These can vary from fairly simple to home-rolled monstrosities that have no place in a work environment.
There's no real simple way of doing this, and though you may be tempted to simply dump the memory at an address like so:
char *buffer = new char[sizeof(Container)];
memcpy(buffer, containerInstance, sizeof(Container));
I'd really suggest against it unless all you have are simple types.
If you want something really simple but not complete, I'd suggest writing your own
printOn(ostream &) member method.
XDR is one way to do this in a platform independent way.