R
rmilh
I'm trying to implement simple, safe and portable string class to be
used from within exception classes. So, the string class must not
throw exceptions and must be counted to prevent unnecessary copying .
Here are relevant parts of a class design:
using namespace std;
class ExceptionString
{
public:
explicit ExceptionString(const char* s) throw();
private:
char* string;
size_t& refCount;
};
// implementation 1
ExceptionString::ExceptionString(const char* s) throw() :
refCount(*new (nothrow) size_t(1)),
string(new (nothrow) char[strlen(s)+sizeof(char)])
{
...
}
The abowe implementation is ok except for in this situation, new
called twice is overkill . So, to get rid of second new one could
write something like this:
// implementation 2
ExceptionString::ExceptionString(const char* s) throw() :
string((new (nothrow) char[sizeof(size_t)+strlen(s)+sizeof(char)])
+ sizeof(size_t)),
refCount(reinterpret_cast<size_t&>(*(string-sizeof(size_t))))
{
...
}
This implementation depends on the order of declaration unless I
redeclare size_t& refCount to be size_t* refCount. Moreover, I'm not
sure wheter or not it is safe to assume that string member points to
properly aligned string.
Now, there must be another way with single allocation that doesn't
suffer from all this limitations. Could you share some ideas?
Robert Milharcic
used from within exception classes. So, the string class must not
throw exceptions and must be counted to prevent unnecessary copying .
Here are relevant parts of a class design:
using namespace std;
class ExceptionString
{
public:
explicit ExceptionString(const char* s) throw();
private:
char* string;
size_t& refCount;
};
// implementation 1
ExceptionString::ExceptionString(const char* s) throw() :
refCount(*new (nothrow) size_t(1)),
string(new (nothrow) char[strlen(s)+sizeof(char)])
{
...
}
The abowe implementation is ok except for in this situation, new
called twice is overkill . So, to get rid of second new one could
write something like this:
// implementation 2
ExceptionString::ExceptionString(const char* s) throw() :
string((new (nothrow) char[sizeof(size_t)+strlen(s)+sizeof(char)])
+ sizeof(size_t)),
refCount(reinterpret_cast<size_t&>(*(string-sizeof(size_t))))
{
...
}
This implementation depends on the order of declaration unless I
redeclare size_t& refCount to be size_t* refCount. Moreover, I'm not
sure wheter or not it is safe to assume that string member points to
properly aligned string.
Now, there must be another way with single allocation that doesn't
suffer from all this limitations. Could you share some ideas?
Robert Milharcic