Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There are three ways the string might reasonably work, but as presented it doesn't fall into any of the three categories. They are:</p> <ol> <li><p>a "value-semantic" object that copies the specified data and maintains ownership of it, just as <code>std::string</code> does</p></li> <li><p>a <code>(const char*, length)</code> const "reference" to some text owned by the caller, which guarantees that text's lifetime will be longer than the "string"'s usage</p></li> <li><p>a <code>(char *, length)</code> reference to a writeable buffer owned by the caller, but into which the "string" object may make updates (perhaps even moving the NUL terminator)</p></li> </ol> <p>We can consider each in turn.</p> <h2>1. value semantics as per `std::string`</h2> <p>The question very explicitly states that this is a "string" class, and that implies (weakly, but we don't have a lot to go...) the class is intended as a general purpose value-semantic string. Assuming for the moment that's true, we can consider the implementation presented: the class simply remembers the address and length of a non-const character buffer specified by the caller without taking ownership of the buffer. Even if from the caller's perspective the string class is being given ownership of that buffer (i.e. the caller won't further modify the content without going through the string API), there's no evidence that the string object has the means to grow the buffer, which is a basic requirement of a general purpose string class.</p> <p>So, if it's a general purpose string, then it should instead make a copy of the value and take ownership. That's best done by re-arranging the data members to:</p> <pre><code>int length; // should really be size_t char *strval; </code></pre> <p>...so that the constructor can use the initialisation list and know the value of length will be populated first, and therefore usable in the initialisation of strval - this removes the need to calculate the string length twice...</p> <pre><code>string(const char* p, int n) : length(strlen(p)), strval(new char[length + 1]) { strcpy(strval, p); } </code></pre> <h2>2. Constant reference to text</h2> <p>If the string is <strong>not</strong> meant to be a general purpose string, then the first and biggest issue with it is the name "string". To work out a better name, let's return to the functionality presented. It remembers the address and current-content-length of a caller-specified buffer: in my experience, that's most often done when the pointer is constant - for example, abstracting non-NUL-terminated substrings within the caller's character buffer - for example, element positions in a memory-mapped file.</p> <p>The second issue - spotted first by Aaron - becomes that the constructor's string parameter is <code>const</code>, and would need to be changed to simply <code>char*</code> to allow <code>strval</code> to be initialised therefrom. Alternatively, if you change <code>strval</code> to <code>const char*</code> we return to the <code>const</code> non-NUL-terminated substring reference that I mentioned finding useful above. Again, an appropriate name should be found, e.g. <code>text_reference</code>, <code>substring_reader</code> or whatever works for you.</p> <h2>3. Non-constant reference to text</h2> <p>The <code>strval</code> pointer as presented is not <code>const</code>, which suggests an object with the ability to overwrite the provided buffer's content, but still doesn't have the ability to lengthen the buffer. This is rarely useful in my experience, though it may be ideal for some particular program's needs. A better name for such a class should be found, not easy!, but for example "buffer_overwriter" hints - to my mind at least - at the length-capped nature and non-<code>const</code> access. Further, the provided constructor only works with already NUL-terminated buffers, but we can imagine a second constructor <code>(char*, int)</code> that removes that requirement and may make the object more widely useful.</p> <p>Otherwise, Greg covers the ground very thoroughly.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload