Let's say I have a C++ class:
template<int N>
class Text {
public:
Text() { }
char _buf[N];
};
It simply encapsulates a C string.
Now, let's say I write a method that will take another Text
object, with a length M
and copy its contents into this object.
template<int N>
class Text {
public:
Text() { }
char _buf[N];
template<int M> void copy(const Text<M> &t) {
strncpy(_buf, t.cstr(), N - 1);
_buf[N - 1] = '\0';
}
};
Is this going to cause an explosion of duplicated object code where the only difference are the constants N
and M
used, especially if I use this copy
method with objects that have lots of different N
and M
?
Since the method itself doesn't depend on M
at all, is there another way to approach this such that I avoid this explosion of duplicated object code?
The most obvious approach is to factor the common bits into a base class, e.g.:
class TextBase {
public:
char* text;
int n;
TextBase(char* text, int N): text(text), n(N) {}
void copy(const TextBase &t) {
strncpy(this->text, t.text, n - 1);
this->text[n - 1] = '\0';
}
};
template<int N>
class Text: public TextBase {
public:
Text(): TextBase(_buf, N) { }
char _buf[N];
};
It trades object size for a potential improvement in code size. It must be obvious because it was the first thing coming to my mind while still waking up. Instead of traveling in terms of a base taking the parameter in a type-erase form avoids the need for extra storage, e.g. (this approach came to my mind when being a bit further away from waking up):
template<int N>
class Text {
public:
Text() { }
char _buf[N];
operator char const*() const { return this->_buf; }
void copy(char const* source) {
strncpy(this->_buf, source, N - 1);
this->_buf[N - 1] = '\0';
}
};
As already mentioned the solution could be a base class with a pure virtual method to get the buffer. There are no additional attribute required and _buf
could be privat.
Something like this:
class TextBase {
public:
virtual const char* cstr() const =0;
};
template<int N>
class Text: public TextBase {
public:
Text() { }
void copy( TextBase &t) {
strncpy(_buf, t.cstr(), N - 1);
_buf[N - 1] = '\0'; }
protected:
virtual const char* cstr() const {
return _buf;
};
private:
char _buf[N];
// ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With