I am learning data structures and algorithms. My teacher told me the following:
push(): push inserts an element in the stack
pop(): pop deletes the last inserted element from the stack
size(): Returns the number of elements in the stack
isempty(): Returns a boolean indicating if the stack is empty
top(): returns the top element of the stack, without removing it; If stack is empty an error is returned.
Where are the implementations of these functions? Are these built-in functions of C++?
Your teacher was explaining the functions available for the generic stack data structure. Those functions aren't implemented anywhere in particular because your teacher was not talking about any specific stack. Your teacher wasn't even talking about C++. Right now you're just learning about what a stack is: they're abstract data structures implementable in any language. They're last-in-first-out containers. Later in your course, you'll learn about trees, queues, heaps, lists, and all sorts of other abstract data structures. In a later lesson, your teacher will probably demonstrate how to implement the functions listed above. The demonstration might even be in C++.
These are member functions for std::stack, which is a container class (template) in the C++ standard library.
You can find the implementation in the <stack> header file.
[Note that it's empty(), not isempty(), though.]
std::stack - it's in the standard library, which is "part" of c++, although it's not a "built-in function"
If you are trying to figure out how to create your own template classes and functions, see
http://www.cplusplus.com/doc/tutorial/templates/
If you want to understand how a stack could be implemented, and what a stack is, read
http://en.wikipedia.org/wiki/Stack_%28data_structure%29
If you want to understand more about containers in C++ STL, read these:
http://www.cplusplus.com/reference/stl/stack/
http://www.cplusplus.com/reference/stl/
Hopefully, these references will help you with asking a more specific question or to request clarification on something you don't yet understand...
To use the stl you would have to include all or part of it in your files, or reference the stl each time you use it.
Here is a link to an implementation of the STL:
http://www.sgi.com/tech/stl/download.html
Related
The Dart core API has two classes that implement the Queue<E> interface, DoubleLinkedQueue<E> and ListQueue<E>.
The documentation of both classes is almost identical, the only difference that is explicitly mentioned is the following note in the ListQueue<E> documentation:
Operations like removeAll and removeWhere are very inefficient. If those are needed, use a DoubleLinkedQueue instead.
What is the actual difference between them implementation-wise and when should which implementation be used?
The DoubleLinkedQueue is basically a Queue implemented on top of a double-linked list. This means that removing elements at arbitrary positions in it is fast, since it only requires the adjustment of pointers.
The ListQueue is implemented on top of a List. First and last are indices into the list. In general this is the more efficient implementation, since it has less memory-overhead than the double-linked list.
You can see both implementations here
Most of the time you want to use the ListQueue. For that reason, the Queue interface defaults to the ListQueue (i.e. Queue() returns a ListQueue).
The DoubleLinkedQueue implementation is mostly useful if you need to selectively remove elements inside the queue. It's a relatively rare scenario, and the main-reason the class is in the dart-libraries, is that the DoubleLinkedQueue existed before the ListQueue. Since we already had the DoubleLinkedQueue we kept it. If we had started out with the ListQueue we probably wouldn't have added the DoubleLinkedQueue.
Classic example is iterator invalidation :
std::string test("A");
auto it = test.insert(test.begin()+1,'B');
test.erase();
...
std::cout << *it;
Do you think having this kind of API is bad design, and will be difficult to learn/use for beginners ?
A costly, performance/memory wise, solution would be, in that type of case, to assign the pointer/iterator to an empty string (or a nullptr, but that's not very helpful) when a clear method is used.
Some precisions
I'm thinking of this design for returning const chars* that can be modified internally (maybe they're stored in a std::vector that can be cleared). I don't want to return a std::string (binary compatibility) and I don't want a get(char*,std::size_t) method because of the size argument that needs to be fetched (too slow). Also I don't want to create a wrapper around std::string or my own string class.
I would recommend reading up on Stepanov's design philosophy (pages 9-11):
[This example] is written in a clear object-oriented style with getters and setters. The proponents of this style say that the advantage of having such functions is that it allows programmers later on to change the implementation. What they forget to mention is that sometimes it is awfully good to expose the implementation. Let us see what I mean. It is hard for me to imagine an evolution of a system that would let you keep the interface of get and set, but be able to change the implementation. I could imagine that the implementation outgrows int and you need to switch to long. But that is a different interface. I can imagine that you decide to switch from an array to a list but that also will force you to change the interface, since it is really not a very good idea to index into a linked list.
Now let us see why it is really good to expose the implementation. Let us assume that tomorrow you decide to sort your integers. How can you do it? Could you use the C library qsort? No, since it knows nothing about your getters and setters. Could you use the STL sort? The answer is the same. While you design your class to survive some hypothetical change in the implementation, you did not design it for the very common task of sorting. Of course, the proponents of getters and setters will suggest that you extend your interface with a member function sort. After you do that, you will discover that you need binary search and median, etc. Very soon your class will have 30 member functions but, of course, it will be hiding the implementation. And that could be done only if you are the owner of the class. Otherwise, you need to implement a decent sorting algorithm on top of the setter-getter interface from scratch and that is a far more difficult and dangerous activity than one can imagine. ...
Setters and getters make our daily programming hard but promise huge rewards in the future when we discover better ways to store arrays of integers in memory. But I do not know a single realistic scenario when hiding memory locations inside our data structure helps and exposure hurts; it is, therefore, my obligation to expose a much more convenient interface that also happens to be consistent with the familiar interface to the C arrays. When we program in C++ we should not be ashamed of its C heritage, but make full use of it. The only problems with C++, and even the only problems with C, arise when they themselves are not consistent with their own logic. ...
My remark about exposing the address locations of consecutive integers is not facetious.
It took a major effort to convince the standard committee that such a requirement is an
essential property of vectors; they would not, however, agree that vector iterators should
be pointers and, therefore, on several major platforms – including the Microsoft one – it
is faster to sort your vector by saying the unbelievably ugly
if (!v.empty()) {
sort(&*v.begin(), &*v.begin() + v.size());
}
than the intended
sort(v.begin(), v.end());
Attempts to impose pseudo-abstractness at the cost of efficiency can be defeated, but at a terrible cost.
Stepanov has a lot of other interesting documents available, especially in the "Class Notes" section.
Yes, there are several rules of thumb regarding OOP. No, I'm not convinced that they are really the best way to do things. When you're working with the STL it makes a lot of sense to do things the STL compatible way. And when your abstraction is low level (like std::vector, which is meant specifically to make working with dynamically allocated arrays easier; i.e., it should be usable almost like an array with some added features), then some of those OOP rules of thumb make no sense at all.
To answer the original question: even beginners will eventually need to learn about iterators, object lifetimes, and what I'll call an object's useful life (i.e., "the object hasn't fallen out of scope, but is no longer valid to use, like an invalidated iterator"). I don't see any reason to try to hide those facts of life from the user, so I personally wouldn't rule out an iterator-based API on those grounds. The real question is what your API is meant to abstract and what's it's meant to expose (similar to the fact that a vector is a nicer array and is meant to expose its array nature). If you answer that, you should have a better idea about whether an iterator-based API makes sense.
As Scott Meyers states in Effective C++: yes it is indeed not a good design to grant access to private/protected members via pointers, iterators or references because you never know what the client code will do with it.
As far as I can remember this should be avoided, and it is sometimes better to create a copy of data members which are then returned to the caller.
It is a bad or faulty implementation rather than design.
As for providing access to private or protected members through pointers, basically it destroys one of the basic OOP principle of Abstraction.
I am unsure though as to what the question is, Yes ofcourse it is bad to have implementation which invalidates iterator. What is the real Q here?
Is it possible to have a vector without specializing it?
My problem is: I have an abstract class N4GestureRecognizer
and a couple of subclasses of it.
So in a Controller class I want to have a vector<N4GestureRecognizer> recognizers_ but since it is abstract I cannot.
How can I store this recognizers in a vector or collection or list or whatever is loop-able in standard c++?
Store them as pointers. Either pure pointers or some smart pointer class.
EXTRA
Actually, pointers are the only way even if the class is not abstracts, but is subclassed and child classes are intended to be used in the vector. Why: std::vector allocates sizeof(T) bytes for each element, but sizeof(derivedFromT) could be bigger than sizeof(T). You will be able to push a child object into the vector, but it can cause unpredictable issues at run time.
Managing vectors of pointers is a pain, of course, but as far as I remember, boost contains some smart pointers to simplify the task.
What you need is a std::vector< std::shared_ptr<N4GestureRecognizer> >.
If your std lib comes without std::shared_ptr (it's part of the next C++ standard, expected to be published next year), it might come with std::tr1::shared_ptr, which is the same (as a addition to the current C++ standard by the official Technical Report 1). If that also fails, there's always boost, which has boost:shared_ptr (which is the predecessor of std::tr1::shared_ptr and std::shared_ptr).
Note: Don't use naked pointers (std::vector<N4GestureRecognizer*>). There's almost no way to make this safe so that it doesn't leak.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 13 years ago.
If I'd like to know how a function written in like standard C++ library work (not just the MSDN description). I mean how does it allocate, manage, deallocate memory and return you the result. where or what do you need to know to understand that?
You can look at the library headers. A lot of functionality is actually implemented there because the library is highly templatized (and templates generally need to be implemented in headers). The location of the headers depends on the compiler, but you should be able to find them quite easily (e.g. search for a file named algorithm).
You may also ask the compiler to preprocess your code to see all the related headers (this will produce extremely long output). With GCC you can do this by g++ -E yoursource.cc.
If what you are looking for isn't implemented in headers, you need the library sources, which are generally not installed by default and which are not even available for commercial compilers such as MSVC. Look for glibc (C library) and libstdc++ (C++ library), which are the ones used by GCC and some other compilers.
In any case, notice that the standard library implementations tend to be rather cryptic due to a lot of underscores being used in variable names and such (to avoid name collisions with user's macros), and often they are also infested with #ifdefs and other preprocessor cruft.
You need to know the techniques used to write C++ libraries. Getting Bjarne Stroustrup's book is a good start. Also, SGI has very detailed documentation on the STL at a suitably high level of abstraction.
If you are going to be investigating the windows based stuff you might want to study the systems part of the windows library.
To complement windows: understanding the Posix specification is also important.
First a few basic data-structure principles, then a note and some links about allocators...
The STL containers use a number of different data structures. The map, set, multimap and multiset are normally implemented as binary trees with red-black balancing rules, for example, and deque is possibly (more impression than knowledge) a circular queue in an array, exploiting an array-doubling or similar growth pattern.
None of the data structures are actually defined by the standard - but the specified performance characteristics limit the choices significantly.
Normally, your contained data is contained directly in the data structure nodes, which are held (by default) in heap allocated memory. You can override the source of memory for nodes by providing an allocator template parameter when you specify the container - more on that later. If you need the container nodes to reference (not contain) your items, specify a pointer or smart-pointer type as the contained type.
For example, in an std::set, the nodes will be binary tree nodes with space in them for an int and the two child pointers, and the metadata that the library needs (e.g. the red/black flag). The binary tree node will not move around your applications address-space, so you can store pointers to your data item elsewhere if you want, but that isn't true for all containers - e.g. an insert in a vector moves all items above the insert point up by one, and may have to reallocate the whole vector, moving all items.
The container class instance is normally very small - a few pointers is typical. For example, the std::set etc usually have a root pointer, a pointer to the lowest-key node and a pointer to the highest-key node, and probably a bit more metadata.
One issue the STL faces is creating and destroying instances in multi-item nodes without creating/destroying the node. This happens in std::vector and std::deque, for instance. I don't know, strictly, how the STL does it - but the obvious approach requires placement new and explicit destructor calls.
Placement new allows you to create an object in an already-allocated piece of memory. It basically calls the constructor for you. It can take parameters, so it can call a copy constructor or other constructor, not just the default constructor.
http://www.devx.com/tips/Tip/12582
To destruct, you literally call the destructor explicitly, via a (correctly typed) pointer.
((mytype*) (void*) x)->~mytype ();
This works if you haven't declared an explicit constructor, and even for built-in types like "int" that don't need destructing.
Likewise, to assign from one constructed instance to another, you make an explicit call to operator=.
Basically, the containers are able to create, copy and destroy data within an existing node fairly easily, and where needed, metadata tracks which items are currently constructed in the node - e.g. size() indicates which items are currently constructed in an std::vector - there may be additional non-constructed items, depending on the current capacity().
EDIT - It's possible that the STL can optimise by using (directly, or in effect) std::swap rather than operator= to move data around. This would be good where the data items are (for example) other STL containers, and thus own lots of referenced data - swapping could avoid lots of copying. I don't know if the standard requires this, or allows but doesn't mandate it. There is a well-known mechanism for doing this kind of thing, though, using a "traits" template. The default "traits" can provide an assignment-using method whereas specific overrides may support special-case types by using a swapping method. The abstraction would be a move where you don't care what is left in the source (original data, data from target, whatever) as long as it's valid and destructible.
In binary tree nodes, of course, there should be no need for this as there is only one item per node and it's always constructed.
The remaining problem is how to reserve correctly-aligned and correctly-sized space within a node struct to hold an unknown type (specified as a template parameter) without getting unwanted constructor/destructor calls when you create/destroy the node. This will get easier in C++0x, since a union will be able to hold non-POD types, giving a convenient uninitialised-space type. Until then, there's a range of tricks that more-or-less work with different degrees of portability, and no doubt a good STL implementation is a good example to learn from.
Personally, my containers use a space-for-type template class. It uses compiler-specific allocation checks to determine the alignment at compile-time and some template trickery to choose from an array-of-chars, array-of-shorts, array-of-longs etc of the correct size. The non-portable alignment-checking tricks are selected using "#if defined" etc, and the template will fail (at compile time) when someone throws a 128-bit alignment requirement at it because I haven't allowed for that yet.
How to actually allocate the nodes? Well, most (all?) STL containers take an "Allocator" parameter, which is defaulted to "allocator". That standard implementation gets memory from and releases it to the heap. Implement the right interface and it can be replaced with a custom allocator.
Doing that is something I don't like to do, and certainly not without Stroustrups "The C++ Programming Language" on my desk. There's a lot of requirements to meet in your allocator class, and at least in the past (things may have improved), compiler error messages were not helpful.
Google says you could look here, though...
http://www2.roguewave.com/support/docs/leif/sourcepro/html/toolsug/12-6.html
http://en.wikipedia.org/wiki/Allocator_%28C%2B%2B%29
Operating system functions to allocate/free memory are not really relevant to the C++ standard library.
The standard library containers will (by default) use new and delete for memory, and that uses a compiler-specific runtime which almost certainly manages its own heap data structure. This approach is generally more appropriate for typical applications use, where the platform-specific operating system heap is usually more appropriate for allocating large blocks.
The application heap will allocate/free memory from the operating system heap, but "how?" and "when?" are platform-specific and compiler-specific details.
For the Win32 memory management APIs, look here...
http://msdn.microsoft.com/en-us/library/ms810603.aspx
I'm sure you can find win64 equivalents if needed.
I haven't this book, but according to its description, http://www.amazon.com/C-Standard-Template-Library/dp/0134376331 includes
-Practical techniques for using and implementing the component
Isn't this what you want?
I'm new to c++ but have set my mind on a specific task that needs me to enable adding a specific chunk of code to be execute whenever any list item is attempted to be changed or read.
The resulting list should behave and look as much as as possible to std::list except for this small exception that would enable me to execute a specific tasks whenever this list is about to be read/written to.
From what i have found out so far, all i could think of is deriving a class from list::iterator and overloading it's operator* and operator= to implement these specific tasks.
Then i should derive a class from std::list and make it use my new iterator type by overloading begin() and end() methods. Or is there a better way of making it use a custom iterator?
That would handle the iterator access but I can see lists can even return pointers to it's members. I guess there is nothing i can do about them and will have to remove this feature from my new list class.
I would appreciate your oppinion on this subject.
Deriving from std::list is almost certainly not the answer. The collections in stl are simply not meant to be derived from and doing so will cause you problems down the road.
The classic example of why is the destructor problem. The destructors in stl collections are not virtual. This will break any logic you place in your derived class destructor if an object is deleted via a reference to the std::list. For example
std::list* pList = new YourNewListClass();
delet pList; // runs std::list::~list()
You'd also need to override much more than the methods on the iterator. It would require changing every method which can possibly mutate the collection.
A more stable approach would be to implement your own std::list style class which follows the standard stl container behavior. You could then include use this list in the places you wanted events without running into the problems with deriving from std::list.
Look at the way that std::deque implements it's functionality as an adaptor of another standard collection. This is the way to go -- use composition not inheritance and wrap the underlying collection to provide your new facilities. For bonus points template your implementation on the underlying collection. For many uses a std::vector will outperform a std::list and your additions should be able to work equally well with whichever of these the user chooses.
First things first..NEVER derive a class from STL containers as they are not meant to be derived. For starters their destructor is not virtual.
The easiest way would be contain a std::list in your own class and providing list like interfaces. In these list like interfaces you can provide any additional tasks you want to perform before/updating the list.
Also, take a look at this design pattern: Decorator
Take a look at boost::transform_iterator<>. It seems to be close to what you're looking for. It calls a functor whenever the operator*() function of the transform_iterator<> is called. The intended use is to transform the object the iterators points to, but there's nothing that says the functor can't do something else and simply return the original value of the pointed to object.
Even if it's not quite what you want, it will probably provide ideas to how you might approach your problem.