newbie: extend string

G

Guest

I want to extend the string class so I wrote this code:
------------------------------
class string2 : public string
{
public:
//string2() {}
//string2(string s) { *this = s; }
string trim()
{
int st = this->find_first_not_of(" \t\r\n");
int ed = this->find_last_not_of(" \t\r\n");
if (st != npos) return this->substr(st, ed - st + 1); else return string();
}
};
------------------------------
As you see, I have no changes in class data (extra variables, virtual functions etc)
I try following code but I fail. Why?
------------------------------
string2 s = static_cast<string2> ( string("this is a test") );
string2 t = (string2) string("this is a test");
------------------------------
when I use 2, commented now, lines in class string2 it works.

Other question: This is correct or I can write it better?
-----------------------------
// vector<string> v;
string temp = string2(v.back()).trim();
-----------------------------
I know, conversion from string2 to string is very easy (& quick) but
conversion from string to string2 with this constructor of string2 is quick?
Maybe it copy whole string to string2 with memory copy operation? (slow)

Thanks for your time
 
R

Ron Natalie

string2 s = static_cast<string2> ( string("this is a test") );
string2 t = (string2) string("this is a test");

It is not correct. First off, trying to extend the string class like this is
fraught with perils. String was not made to be derived from. You're
out of luck if someone does something like:

string* sp = new string2;
delete string2;

Notwithstanding that, with the converting constructor (you might want to
consider making it take a const string&) that you added should work. You
shouldn't even need the cast to string2();
Why not just write a trim function that is not a member.

std::string trim(const string& s) {
....
 
V

Victor Bazarov

Ron Natalie said:
It is not correct. First off, trying to extend the string class like this is
fraught with perils. String was not made to be derived from. You're
out of luck if someone does something like:

string* sp = new string2;
delete string2;

This of course ought to be

delete sp;

(I am sure that's how Ron intended it)
 
R

Rolf Magnus

Ron said:
It is not correct. First off, trying to extend the string class like
this is fraught with perils. String was not made to be derived from.

Says who?
You're out of luck if someone does something like:

string* sp = new string2;
delete string2;

Who would ever do such a thing? Why would you allocate a string with new
at all?
 
C

Cy Edmunds

I want to extend the string class so I wrote this code:
------------------------------
class string2 : public string
{
public:
//string2() {}
//string2(string s) { *this = s; }
string trim()
{
int st = this->find_first_not_of(" \t\r\n");
int ed = this->find_last_not_of(" \t\r\n");
if (st != npos) return this->substr(st, ed - st + 1); else return string();
}
};
------------------------------
As you see, I have no changes in class data (extra variables, virtual functions etc)
I try following code but I fail. Why?
------------------------------
string2 s = static_cast<string2> ( string("this is a test") );
string2 t = (string2) string("this is a test");
------------------------------
when I use 2, commented now, lines in class string2 it works.

Other question: This is correct or I can write it better?
-----------------------------
// vector<string> v;
string temp = string2(v.back()).trim();
-----------------------------
I know, conversion from string2 to string is very easy (& quick) but
conversion from string to string2 with this constructor of string2 is quick?
Maybe it copy whole string to string2 with memory copy operation? (slow)

Thanks for your time

Aside from the technical objections raised by Ron, it is illogical to have
two different string types which differ so little. Imagine a large body of
software which uses std::string in some places and string2 in others. It
would be needlessly confusing for everybody.

I heartily agree with Ron that a standalone trim() function taking a
std::string argument solves the problem much more elegantly. Nobody would
have to learn a new data type, no conversions back and forth would be
necessary, and the programming staff can take your trim() function or leave
it as they please.

I know that some people think that such solutions are not sufficiently
"object oriented", whatever that means. IMHO that opinion would be entirely
fallacious in this case.
 
C

Cy Edmunds

Rolf Magnus said:
Says who?

Sez me.
Who would ever do such a thing?

Are you kidding? Do you see the stuff that gets posted here every day?

Why would you allocate a string with new

Who knows? Who cares? Why set a trap for the client and then blame him for
falling into it? The practice of deriving from classes like std::string is
fundamentally unsound for reasons which are well known. If you do it, any
problems it causes your client are YOUR fault, whether you approve of the
client's programming style or not.
 
R

Rob Williscroft

Cy Edmunds wrote in
Rolf Magnus said:
Ron Natalie wrote:
[snip]
Who would ever do such a thing?

Are you kidding? Do you see the stuff that gets posted here every day?

And what other than "usenet is a strange place", does that prove ?
Why would you allocate a string with new

Who knows? Who cares? Why set a trap for the client and then blame him
for falling into it? The practice of deriving from classes like
std::string is fundamentally unsound for reasons which are well known.

If the reason's are "well known", whats the problem ? surely it is
"well known" too.
If you do it, any problems it causes your client are YOUR fault,
whether you approve of the client's programming style or not.

I'll see you with a "delete []" and raise you a "reinterpret_cast",

So if the client does:

delete [] reinterpret_cast< int * >( sp );

Its my fault then ?

Rob.
 
D

Dietmar Kuehl

I want to extend the string class so I wrote this code:

It is a misconception that "extending" a class is done by derivation: you
have listened to much to people who try to slam all their problems with the
OO hammer. In C++ (and in languages with a similar object model) you only
derive [publically] for modifying the base class' behavior. This effectively
means that the base class has to have virtual functions in the first place:
otherwise it is neither suitable nor intended for derivation.

Object should be responsible for maintaining their internal restrictions
and resources. That's it. Extending the behavior of a class is thus done
by providing functions operating on the objects. These can be class members
but of some other class or, at least in C++, non-member functions.

You "extended" your string to provide a function for trimming leading and
trailing whitespace. Actually, the same algorithm also works for other
containers of characters - or, with just a little bit of generalization
actually for any container of elements: matching certain whitespace is just
a special case of matching a condition.

From this point of view, it turns out that the standard library's string
class is actually misdesigned: it has an unnecessary fat interface. There
is in general a reason for a relatively fat interface for string because
this can be used to provide certain optimizations for typical string
operations like eg. sharing the representation between multiple strings.
Unfortunately, this goal is dwarved by some of the member functions, notably
the interface for non-const iterators and character access.
 
C

Cy Edmunds

Rob Williscroft said:
Cy Edmunds wrote in
Rolf Magnus said:
Ron Natalie wrote:
[snip]
You're out of luck if someone does something like:

string* sp = new string2;
delete string2;

Who would ever do such a thing?

Are you kidding? Do you see the stuff that gets posted here every day?

And what other than "usenet is a strange place", does that prove ?

Don't be such a flower child. You think the posters here are not C++ users?
They are trying to use C++ as best they know how, as frightening as that
seems. One of the specific abuses I see all the time is massive overuse of
new(). I have no reason to believe this tendency is somehow limited to
usenet users.
If the reason's are "well known", whats the problem ? surely it is
"well known" too.

You remind me of a guy who keeps a pitbull chained up in his yard. Some kid
gets mauled and he says, "The kid shouldn't have come into my yard in the
first place. Plus, I have a 'beware of dog' sign."

I have no sympathy for such a pet owner. Similarly I have no sympathy for a
seasoned C++ programmer who sets traps for less capable clients. C++ is a
complex language which gives you lots of control. As you well know, it is
possible (actually easy) to write a class which invokes undefined behavior
on things like

y = x;

Experienced programmers have a responsibility to make their code as
bulletproof as possible.
If you do it, any problems it causes your client are YOUR fault,
whether you approve of the client's programming style or not.

I'll see you with a "delete []" and raise you a "reinterpret_cast",

So if the client does:

delete [] reinterpret_cast< int * >( sp );

Its my fault then ?

No. You didn't define any of the things in your example which is therefore
moot.
 
R

Rob Williscroft

Cy Edmunds wrote in
Rob Williscroft said:
Cy Edmunds wrote in
Ron Natalie wrote:

[snip]



You're out of luck if someone does something like:

string* sp = new string2;
delete string2;

Who would ever do such a thing?

Are you kidding? Do you see the stuff that gets posted here every
day?

And what other than "usenet is a strange place", does that prove ?

Don't be such a flower child.

I've no idea what that means.
You think the posters here are not C++
users? They are trying to use C++ as best they know how,

And most who are making the mistakes are trying to learn to
understand and use it better.
as
frightening as that seems. One of the specific abuses I see all the
time is massive overuse of new(). I have no reason to believe this
tendency is somehow limited to usenet users.

There is no problem with using new:

boost::shared_ptr< T > ptr( new T( /* whatever */ ) );

is fine, its people who use delete when they don't have all the
facts that have the problem, best *not* to use delete :).
You remind me of a guy who keeps a pitbull chained up in his yard.
Some kid gets mauled and he says, "The kid shouldn't have come into my
yard in the first place. Plus, I have a 'beware of dog' sign."

So I should expect my code to be used/maintained by children and code
accordingly ?
I have no sympathy for such a pet owner. Similarly I have no sympathy
for a seasoned C++ programmer who sets traps for less capable clients.
C++ is a complex language which gives you lots of control. As you well
know, it is possible (actually easy) to write a class which invokes
undefined behavior on things like

y = x;

Experienced programmers have a responsibility to make their code as
bulletproof as possible.

Since C++ gives me the ability to "shoot myself in the foot",
how come its such a *sin* to write efficient code that allows others
(who should know better and mostly do) to do the same.
If you do it, any problems it causes your client are YOUR fault,
whether you approve of the client's programming style or not.

I'll see you with a "delete []" and raise you a "reinterpret_cast",

So if the client does:

delete [] reinterpret_cast< int * >( sp );

Its my fault then ?

No. You didn't define any of the things in your example which is
therefore moot.

How is that different from delete sp in

string *sp = new string2;
delete sp;

Simply codeing delete sp when your not aware of what sp really
points to is no better (or sensible or mature) then my fecicious
delete [] reinterpret_cast< int * >( sp );

Rob.
 
L

lilburne

Cy said:
One of the specific abuses I see all the time is massive overuse of
new(). I have no reason to believe this tendency is somehow limited to
usenet users.


One of my pet peeves too. I've not quite got to the bottom
of why they are used so frequently but they seems to go hand
in hand with calls to functions that take a pointer argument.

Experienced programmers have a responsibility to make their code as
bulletproof as possible.

One consequence of a bug ought to be a determination of how
it occurred. Whether the cause was a simple mistake or the
result of some failure in the class design, API, language
construct used, etc. Analysis of the causes should be fed
back into the development process to try to reduce the
likelihood of a repetition.
 
L

lilburne

Rob said:
Cy Edmunds wrote in




There is no problem with using new:

boost::shared_ptr< T > ptr( new T( /* whatever */ ) );


The problem is with code like this:

T* t = new T;
doStuff(t);
delete t;

when they could just as easily use:

T t;
doStuff(&t);

new and delete are expensive operations and tend to fragment
the heap.

Since C++ gives me the ability to "shoot myself in the foot",
how come its such a *sin* to write efficient code that allows others
(who should know better and mostly do) to do the same.


For the same reason that if one is responsible one doesn't
leave a loaded gun lying around for any one to pick up, and
one doesn't leave bare live electric wires hanging out of
the walls in public places.
 
R

Rob Williscroft

lilburne wrote in
The problem is with code like this:

It has problems, but they aren't the problems this thread is about,
and T's author can do nothing about them.
T* t = new T;
doStuff(t);
delete t;

when they could just as easily use:

T t;
doStuff(&t);

new and delete are expensive operations and tend to fragment
the heap.

Nope, that *isn't* the problem with the above code, exception
saftey is. If T is a simple class then maybe the only real
problem is potential memory leak.
For the same reason that if one is responsible one doesn't
leave a loaded gun lying around for any one to pick up, and
one doesn't leave bare live electric wires hanging out of
the walls in public places.

That comparison only holds if your writing software that can
cause injury or death if it goes wrong, would you seriously
employ a java/VB/C# (or novice) programmer as a C++ programmer
to do such a thing ?

Rob.
 
L

lilburne

Rob said:
lilburne wrote in



Nope, that *isn't* the problem with the above code, exception
saftey is. If T is a simple class then maybe the only real
problem is potential memory leak.

What has exception safety got to do with it? Cy Edwards was
talking about the 'massive over use of new()'.

That comparison only holds if your writing software that can
cause injury or death if it goes wrong, would you seriously
employ a java/VB/C# (or novice) programmer as a C++ programmer
to do such a thing ?

I'd hope that any organisation that was writing life
threatening software had in place procedures/guidelines to
reduce the likelihood that its 'coding gurus' weren't
exploiting the ability of C++ to shoot themselves in the foot.

However, be that as it may, even for non life threatening
software one shouldn't be designing landmines into the code
for the unwary to stumble upon.
 
C

Cy Edmunds

lilburne said:
One of my pet peeves too. I've not quite got to the bottom
of why they are used so frequently but they seems to go hand
in hand with calls to functions that take a pointer argument.

Well, I think experience with Java and/or Visual Basic sometimes has
something to do with it.
 
R

Rob Williscroft

lilburne wrote in
Rob said:
lilburne wrote in
[snip]
Nope, that *isn't* the problem with the above code, exception
saftey is. If T is a simple class then maybe the only real
problem is potential memory leak.

What has exception safety got to do with it? Cy Edwards was
talking about the 'massive over use of new()'.

And the context before that was deleting a derived object via a
pointer to a base object.
I'd hope that any organisation that was writing life
threatening software had in place procedures/guidelines to
reduce the likelihood that its 'coding gurus' weren't
exploiting the ability of C++ to shoot themselves in the foot.

Indeed. But not calling delete is a better rule than don't
derive from a class without a virtual dtor.
However, be that as it may, even for non life threatening
software one shouldn't be designing landmines into the code
for the unwary to stumble upon.

pitbull, loaded gun, landmines ! Sorry I'm all metaphored out.


Rob.
 
L

lilburne

Cy said:
Well, I think experience with Java and/or Visual Basic sometimes has
something to do with it.

Could be, though they don't seem to be so keen on new when
they are passing references about. I think either the whips
ought to come out, or an afternoons tutorial session is in
order.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,160
Messages
2,570,889
Members
47,422
Latest member
LatashiaZc

Latest Threads

Top