Mathieu Malaterre wrote:
On Feb 19, 2008 5:43 AM, Gonzalo Garramuño <[EMAIL PROTECTED]> wrote:
Mathieu Malaterre wrote:
Ok this was yet-another-weird-dll thingy, one cannot do:
class GDCM_EXPORT String : std::string { ... }
Please, learn a little bit more about C++.
Oh thank you ! I'll take your advice right away, mister expert. So
could you please let me know why *in my particular case* this is
wrong:
1. I did not add any data member
2. I did not overload the dstor
GDCM_EXPORT tells me you are using this in a library.
The reason this is wrong is this. Say you write a function to get a
exension of a filename as uppercase:
GDCM_EXPORT MyString get_extension( const MyString& b )
{
MyString ext = b.to_upper();
// etc... do some other stuff like find '.' and substr
return ext;
}
Now... this will work. But.... now func() can only be used with your
particular MyString class. However, if you had done:
namespace str {
// to_upper implementation not shown
GDCM_EXPORT std::string to_upper( const std::string& b );
GDCM_EXPORT std::string get_extension( const std::string& b )
{
std::string ext = to_upper( b );
// etc... do some other stuff like find '.' and substr
return ext;
}
}
With this, the code for both to_upper() and get_extension() can be
safely be reused and works for *all* std::string objects. You don't
force people to use your own string library. This makes your library
more attractive and easier to reuse in other code.
Even, if you did not do 1 or 2, you might have done 3:
3. Yo might have overloaded (replaced) a string function.
class MyString : public std::string
{
public:
// silly example, but same applies to add, operator<<, etc.
size_type size() { return std::string::size() + 1; }
};
int main()
{
MyString* s = new MyString;
std::string* c = static_cast< std::string* >( s ); // correct
std::cerr << c->size() << std::endl; // which size() gets called?
// not yours,
// but the one in std::string
return 0;
}
This example for 3) is very simple and obvious but in big programs this
issue may be more confusing as the distintion of what a pointer really
points to becomes more blurry.
If you have only added non-conflicting functions in MyString to
std::string, what you have is safe but potentially not so beneficial.
You might either do as I showed and place your additional functions in a
namespace and keep using std::string everywhere (which makes your
library nice to use and probably popular) or create your own string
class, without deriving anything (and yes, you do need to create a lot
of code for doing a good string class -- it is C++ after all), or create
a proxy string class thru containment of std::string (which is like
creating your own string class from scratch, but a tad simpler):
class MyString
{
std::string str;
public:
typedef std::string::size_type size_type;
// other typedefs similar to std::string...
public:
MyString() {}
MyString(const MyString& b) : str(b.str) {}
MyString(const std::string& b) : str(b) {}
// auto cast to string - optional (only if lazy, may not be wanted)
operator std::string() const { return str; }
// dispatch size function
inline size_type size() const { return str.size(); }
// my functions - not shown
void to_upper();
// .... dispatch others, etc...
// also remember to add operator=(const std::string& b)
};
This avoids you having to actually write your (potentially buggy) code
to the string functions, as you just dispatch the operations to the
std::string inside your class. And the operator to std::string() and
copy constructor of std::string allows your class to interact with
std::string functions and elements rather seamlessly. It is still
verbose, but not *THAT* much. And the code is probably safer to use
through pointers and easy to extend without conflicts.
Please do not copy some random comment found on the internet and
instead comment on my particular implementation with the following 1
and 2 restrictions. Thanks.
It is not some "random comment". It is good design advice that sadly
applies to all C++ STL classes.
For more information, refer to a good C++ book. IIRCC, Scott Meyer's
Effective STL and Effective C++, covers this and other problems with all
the pitfalls in a very thorough fashion.
--
Gonzalo Garramuño
[EMAIL PROTECTED]
AMD4400 - ASUS48N-E
GeForce7300GT
Xubuntu Gutsy
_______________________________________________
CMake mailing list
CMake@cmake.org
http://www.cmake.org/mailman/listinfo/cmake