|
-
June 28th, 2011, 05:50 AM
#1
Stack/Queue Question
Hello,
first of all if i tried to create a personal stack but compiler reports me these errors:
MyStack.cpp:8: error: template argument required for ‘class StackMio’
MyStack.cpp:8: error: expected template-name before ‘<’ token
The code is:
Code:
#ifndef STACKMIO_H
#define STACKMIO_H
#include<list>
template <class T>
class StackMio : private list <T>
{
public:
void push(const T& value)
{
push_front(value);
}
void pop(const T& value)
{
pop_front(value);
}
void print()
{
for(list<T>::iterator it=this->begin();it!=this->end();it++)
cout<<*it;
}
};
#endif
Where are the errors? It's the first time i create a template so.. 
Second question: Can I use iterators like in the "Print" function? I read that the iterators can't be used with queue, stacks etc...So how I could "slide" my Stack/Queue? Thanks
-
June 28th, 2011, 05:56 AM
#2
Re: Stack/Queue Question
You aren't showing how you are using the template (and that is what the error is about).
-
June 28th, 2011, 05:56 AM
#3
Re: Stack/Queue Question
Also ...
1. You need to qualifier 'list' with 'std::' (edit: and for the cout)
2. On the for loop, you need a 'typename'
see below:
Code:
#ifndef STACKMIO_H
#define STACKMIO_H
#include<list>
template <class T>
class StackMio : private std::list<T>
{
public:
void push(const T& value)
{
push_front(value);
}
void pop(const T& value)
{
pop_front(value);
}
void print()
{
for(typename std::list<T>::iterator it=this->begin();it!=this->end();it++)
std::cout<<*it;
}
};
#endif
3. std::stack already exists
Last edited by Philip Nicoletti; June 28th, 2011 at 06:01 AM.
-
June 28th, 2011, 06:11 AM
#4
Re: Stack/Queue Question
OK perfect i forget "using namespace std" and iostream... I know that stack exist, but i'm preparing for an exam and i want to know how i can create my own stack/queue etc...So in a main i can't use for example StackMio<int>::iterator etc because it doesn't exist?
-
June 28th, 2011, 07:04 AM
#5
Re: Stack/Queue Question
I suggest that you use composition instead of private inheritance. It'll probably be easier for you to think about.
-
June 28th, 2011, 08:24 AM
#6
Re: Stack/Queue Question
 Originally Posted by Falko-tux
OK perfect i forget "using namespace std" and iostream... I know that stack exist, but i'm preparing for an exam and i want to know how i can create my own stack/queue etc...So in a main i can't use for example StackMio<int>::iterator etc because it doesn't exist?
Correct. But you can typedef them. And you should prefer composition over of private inheritance because a stack isn´t a list.
Code:
template<typename T>
class StackMio
{
public:
typedef typename std::list<T>::const_iterator const_iterator;
const_iterator begin() const
{
return Container_.begin();
}
const_iterator end() const
{
return Container_.end();
}
...
std::list<T> Container_;
};
- Guido
-
June 28th, 2011, 09:07 AM
#7
Re: Stack/Queue Question
 Originally Posted by Falko-tux
OK perfect i forget "using namespace std"
You shouldn't put a using statement in a header file. Just fully-qualify everything.
-
June 28th, 2011, 12:42 PM
#8
Re: Stack/Queue Question
Thanks to everybody
-
June 28th, 2011, 12:59 PM
#9
Re: Stack/Queue Question
 Originally Posted by GNiewerth
And you should prefer composition over of private inheritance because a stack isn´t a list.
Private inheritance does not imply that a stack is a list.
-
June 28th, 2011, 03:23 PM
#10
Re: Stack/Queue Question
Scott Meyers and many others consider private inheritance as
"is implemented in terms of" (item 42 in Effective C++ Second Edition).
There is some disagreement on this board ...
http://www.codeguru.com/forum/showthread.php?t=412309
-
June 28th, 2011, 06:43 PM
#11
Re: Stack/Queue Question
 Originally Posted by laserlight
Private inheritance does not imply that a stack is a list.
Not to the outside world, but the derived class can assign an instance of itself to a variable/pointer/reference of/to the type it privately inherits, so in certain context a stack is not a list, while in another it is. Quite a messy situation.
-
June 29th, 2011, 02:01 AM
#12
Re: Stack/Queue Question
 Originally Posted by TheGreatCthulhu
Not to the outside world, but the derived class can assign an instance of itself to a variable/pointer/reference of/to the type it privately inherits, so in certain context a stack is not a list, while in another it is. Quite a messy situation.
It's just a play with words. The mess goes away as soon as you stop using inheritance and is-a interchangibly. The stack is-a list in "the inside world" because you say so, not because you use private inheritance.
Never assign responsibilities to C++ it has never assumed. C++ doesn't define modeling relationships, you do. C++ only supplies language constructs to facilitate your modeling.
Last edited by nuzzle; June 29th, 2011 at 02:48 AM.
-
June 29th, 2011, 07:17 AM
#13
Re: Stack/Queue Question
 Originally Posted by nuzzle
It's just a play with words. The mess goes away as soon as you stop using inheritance and is-a interchangibly. The stack is-a list in "the inside world" because you say so, not because you use private inheritance.
Never assign responsibilities to C++ it has never assumed. C++ doesn't define modeling relationships, you do. C++ only supplies language constructs to facilitate your modeling.
You have a point, but that is not entirely true. You can't just pick any language construct and map it to an arbitrary relationship, as defined by your modeling paradigm. Why? Because logical relationships require certain conditions to be true, make certain assumptions about the general mechanisms that support the semantics. Language constructs impose some of these constraints or capabilities, so at some level they have an impact on what kind of logical relationships they can represent. But, from there, you can have even more specific interpretations of the relationship, that have nothing to do with the language itself.
My point was, within the scope of the class, you can write
Base *pBase = new PrivatelyDerived();
Within the scope of the class, it's almost as if the keyword private wasn't even used. Within, you can do the same things you can do with public inheritance.
Given all that, I think you can safely say that as far as PrivatelyDerived is concerned, PrivatelyDerived is-a Base (or can be considered as such). Of course, you, as the class' designer, can choose to ignore this fact, and than that relationship will have different semantics, but then you better (1) document that with big flashy letters, and (2) better have a d4mn good reason to use private inheritance.
Because private inheritance, no matter how you interpret it, introduces the same problems as public inheritance, along the lines of the semantic fragile base class problem you spoke of yourself in another thread. (Of course, there is a way to introduce the same set of problems using delegation, but only if you try hard .)
For most people, it is hard to see what this class of problems actually is, because they are so subtle an stem from all the convoluted and often not-obvious interaction between a class and a superclass. I mean, if you're unlucky, and if some bad design is involved you can even break the base class just by deriving from it (that would be some sort of "semantic fragile subclass problem"). And when I say break, I don't mean it-wont-compile break; I mean it-compiles-but-it-doesn't-work kind of break.
These problems are all related to the fact that, sooner or later, the code will change. If it's done by someone else, or even by the same developer, but after a relatively long (read: long enough) pause, then if the semantics are not well documented, or even if the documentation isn't studied properly, chances are that the the developer will try to reconstruct the logical model from the code, thus being deceived by the language constructs themselves (but, the language is not to blame).
Good code is its own best documentation. As you're about to add a comment, ask yourself, 'How can I improve the code so that this comment isn't needed?' Improve the code and then document it to make it even clearer. -- Steve McConnell, software engineer and author, from Code Complete My point is, when you see
class PrivatelyDerived : private Base it does tell you something. You just can't be sure what is it exactly that it tries to say, at leas not just based on that.
-
June 30th, 2011, 01:39 AM
#14
Re: Stack/Queue Question
 Originally Posted by TheGreatCthulhu
Given all that, I think you can safely say that as far as PrivatelyDerived is concerned, PrivatelyDerived is-a Base (or can be considered as such). Of course, you, as the class' designer, can choose to ignore this fact, and than that relationship will have different semantics, but then you better (1) document that with big flashy letters, and (2) better have a d4mn good reason to use private inheritance.
Again, this becomes a problem only becuse you define inheritance to always constitute a modeling relationship. It's a definition you impose on C++. Then you claim that because you can tweak inheritance into breaking the modeling relationship there's something wrong with inheritance. But this doesn't follow because inheritance is a language construct defined by the C++ standard and not whatever people want it to be or say it is.
Even so, if you look at this
Base *pBase = new PrivatelyDerived();
for what it is namely an implementation detail your perceived problem goes away. This possible usage doesn't influence your design, it's hidden implementation.
Should you do it? Well that's left to your good judgement (as often in C++) but the fact that you can do it is not an argument against private inheritance. C++ allows you to do pretty much what you like in private and that's good.
Last edited by nuzzle; June 30th, 2011 at 08:21 AM.
-
June 30th, 2011, 05:54 PM
#15
Re: Stack/Queue Question
I totally understand what are you saying and the separation you're trying to make, and I respect your view. I just don't agree all the way - speaking of programing in general (not just C++), i think it's even counterproductive.
I didn't chose that quote at random: in my mind, an ideal language has a syntax that makes it crystal clear what the intentions of the coder were, and a language where the language features themselves are self-documenting. Of course, in real life, that's probably not possible, except perhaps in some ugly, cumbersome form. But I think a language can find the right balance.
C++ programers often consider C#'s restrictions as some sort of hand-holding, even an insult to the programmer, but they are completely missing the point. And the point is: unless the more complicated, more error-prone way has some huuuuuuuuge benefit, KISS - prevention is better than cure!
It's like saying a safety gate on a dangerous staircase is an insult to Man's intellect. It's just a (sub)set of principles/good-practices embodied into a language, and the price to pay for it is negligible.
I mean, the best designed code often minimizes the possibility of it being misused by clients (accidentally or on purpose) - why shouldn't a programing language strive to do the same?
So that we could concentrate on what really matters instead?
And it's not like these C++ features came first, and then someone said: hey, let's use all this cool stuff and create a modeling paradigm out of it. They were introduced specifically to support OO. Along with a hybrid feature or two. So I argue that language constructs do carry meaning, do carry certain implications about the logical model, at least to some extent.
 Originally Posted by nuzzle
Then you claim that because you can tweak inheritance into breaking the modeling relationship there's something wrong with inheritance. But this doesn't follow because inheritance is a language construct defined by the C++ standard and not whatever people want it to be or say it is.
Even so, if you look at this
Base *pBase = new PrivatelyDerived();
for what it is namely an implementation detail your perceived problem goes away. This possible usage doesn't influence your design, it's hidden implementation.
About the design: It shouldn't, but it could.
However, it is an implementation detail of the class, not of the language. The class is not the issue here. In fact, if you consider the syntax as some sort of a public interface of the language itself - then your argument does not hold.
BTW, my intention was not to "tweak inheritance" in order to break the proposed relationship, quite the opposite - I was trying to prove that that the code implies that we're, in fact, dealing with something akin to an is-a relationship, at least in part, at least in the scope of the class. But a one that pretends that it is something else. You're gonna say: only because I'm interpreting it as such. But I'm claiming that language constructs are not completely devoid of meaning - they can't be, it comes from the mechanisms they are backed with.
Don't get me wrong: I'm not saying C++ is bad or something. I'm just saying that I don't see significant added value in features like protected and private inheritance to warrant their inclusion in the language. I believe C++ programmers could live without them just fine.
But, we're polluting the thread, this is way off-topic. And again, I respect your position, and I'm not claiming I'm right no matter what.
Last edited by TheGreatCthulhu; June 30th, 2011 at 05:57 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|