[C++] Multiple Inheritance and the STL
Author |
Message |
wtd
|
Posted: Sat Apr 09, 2005 12:52 am Post subject: [C++] Multiple Inheritance and the STL |
|
|
The goal
So, let's build a class which allows for the construction of simple HTML tags. Now, we'll be doing a lot of string concatenation, so we want something more efficient that constantly creating a lot of extra std::string objects. Fortunately the STL provides just such a thing in std::stringstream.
We'll only be putting things into a stringstream, so we can use std::ostringstream. We'll also want a way to keep track of which tag we're in, so a std::stack is also going to be needed.
First try
Let's take a first stab at it.
c++: | #include <string>
#include <sstream>
#include <stack>
#include <iostream>
using namespace std;
class tag_stream
{
private:
ostringstream stream;
stack<string> current_tag;
public:
void start_tag(string tag_name);
void end_tag();
string str() const;
template <typename _t>
friend tag_stream& operator<<(tag_stream& ts, const _t& s);
}; |
And implementation:
c++: | void tag_stream::start_tag(string tag_name)
{
current_tag.push(tag_name);
stream << "<" << tag_name << ">";
}
void tag_stream::end_tag()
{
stream << "</" << current_tag.top() << ">";
current_tag.pop();
}
string tag_stream::str() const
{
return stream.str();
}
template <typename _t>
tag_stream& operator<<(tag_stream& ts, const _t& s)
{
ts.stream << s;
return ts;
} |
Now, you should notice that we're basically just duplicating the functionality that ostringstream possesses already, and a tag_stream is a ostringstream.
Single inheritance
We can simplify things a bit by just having tag_stream be a subclass of ostringstream.
c++: | #include <string>
#include <sstream>
#include <stack>
#include <iostream>
using namespace std;
class tag_stream : public ostringstream
{
private:
stack<string> current_tag;
public:
void start_tag(string tag_name);
void end_tag();
}; |
And the implementation:
c++: | void tag_stream::start_tag(string tag_name)
{
current_tag.push(tag_name);
(*this) << "<" << tag_name << ">";
}
void tag_stream::end_tag()
{
(*this) << "</" << current_tag.top() << ">";
current_tag.pop();
} |
Multiple inheritance
We're still working too hard, having that current_tag variable hanging around. But we shouldn't inherit from stack since a tag_stream isn't a stack, right? But, it sort of is a stack. But still, we don't want to be able to manipulate the stack from outside the class, so we can't inherit, right?
Ah, but we can. We simply use either private or protected inheritance. This type of inheritance also means that the program doesn't consider a tag_stream to be a stack.
c++: | #include <string>
#include <sstream>
#include <stack>
#include <iostream>
using namespace std;
class tag_stream : public ostringstream, protected stack<string>
{
public:
void start_tag(string tag_name);
void end_tag();
}; |
And the implementation:
c++: | void tag_stream::start_tag(string tag_name)
{
push(tag_name);
(*this) << "<" << tag_name << ">";
}
void tag_stream::end_tag()
{
(*this) << "</" << top() << ">";
pop();
} |
We wanted protected inheritance here because subclasses of tag_stream may want to directly manipulate the stack.
One last simplification
Since tag_stream has no private members, we can simply declare it as a struct. Also, we'll add a simple test.
c++: | #include <string>
#include <sstream>
#include <stack>
#include <iostream>
using namespace std;
struct tag_stream : public ostringstream, protected stack<string>
{
void start_tag(string tag_name);
void end_tag();
};
int main()
{
tag_stream s;
s.start_tag("html");
s << "hello";
s.end_tag();
cout << s.str() << endl;
return 0;
}
void tag_stream::start_tag(string tag_name)
{
push(tag_name);
(*this) << "<" << tag_name << ">";
}
void tag_stream::end_tag()
{
(*this) << "</" << top() << ">";
pop();
} |
|
|
|
|
|
![](images/spacer.gif) |
Sponsor Sponsor
![Sponsor Sponsor](templates/subSilver/images/ranks/stars_rank5.gif)
|
|
![](images/spacer.gif) |
Martin
![](http://www.compsci.ca/wiki/images/4/46/CanadianStickUp.jpg)
|
Posted: Sat Apr 09, 2005 8:07 pm Post subject: (No subject) |
|
|
I would highly recommend the book 'The C++ Standard Library' by Nicolai M. Josuttis for anyone who would like to learn more about the STL. |
|
|
|
|
![](images/spacer.gif) |
|
|