ptypes

string


You are looking at an old revision of the page string. This revision was created by Natalie Adams.

Table of Contents

initial page

Intro

The string class implements dynamically allocated reference-counted 8-bit character strings. The string class is a mixture of L-type and null-terminated strings: it has both the length indicator and the terminating null-symbol. The length of a string is theoretically limited to INT_MAX, and practically is limited to the amount of virtual memory space available to the application.

A string object itself contains only a reference to the first character of the string buffer. A string object can be implicitly converted to a null-terminated string, either a variable or passed as an actual parameter, thus allowing to combine both PTypes strings and traditional C strings in your application. A string object converted to char* or const char* never returns NULL pointers: it guarantees to always point to some data, even if the string is zero-sized.

The reference counting mechanism works transparently (known also as copy-on-write) and safely with regard to multithreading. You can manipulate string objects as if each object had its own copy of string data. Whenever you modify a string object the library safely detaches the buffer from all other string objects that may be using the same buffer and creates a unique copy so that changes won't affect the other "holders" of this string.

NOTE on multithreading: the dynamic string objects themselves are NOT thread-safe. In other words, each thread can manipulate objects (variables) of type string only within their scope. However, it is safe to pass strings as (copy) parameters when, for example, sending a message to a concurrent thread through a message queue. Whenever the recipient thread tries to modify the string, the shared data buffer is safely detached.

The string class is declared in <ptypes.h>.

Constructor/destructors

Operators

#include 

class string {
    // assignment
    string& operator =(const char*);
    string& operator =(char);
    string& operator =(const string&);
    friend void assign(string&, const char* buf, int len);

    // concatenation
    string& operator +=(const char*);
    string& operator +=(char);
    string& operator +=(const string&);
    string  operator +(const char*) const;
    string  operator +(char) const;
    string  operator +(const string&) const;
    friend  string operator +(const char*, const string&);
    friend  string operator +(char c, const string&);

    // comparison
    bool operator ==(const char*) const;
    bool operator ==(char) const;
    bool operator ==(const string&) const;
    bool operator !=(const char*) const;
    bool operator !=(char c) const;
    bool operator !=(const string&) const;

    // indexed character access, 0-based
    char& string::operator[] (int index);
    const char& string::operator[] (int index) const;
}

A string object can be constructed in 5 different ways:

  • default constructor string() creates an empty string.
  • copy constructor string(const string& s) creates a copy of the given string s. Actually this constructor only increments the reference count by 1 and no memory allocation takes place.
  • string(char c) constructs a new string consisting of one character c.
  • string(const char* s) constructs a new string object from a null-terminated string. If s is either NULL or is a pointer to a null character, an empty string object is created. This constructor can be used to assign a string literal to a string object (see examples below).
  • string(const char* s, int len) copies len bytes of data from buffer s to the newly allocated string buffer.

Destructor ~string() decrements the reference count for the given string buffer and removes it from the dynamic memory if necessary.

Examples:

string s1;             // empty string
string s2 = s1;        // copy
string s3 = 'A';       // single character
string s4 = "ABCabc";  // string literal
char* p = "ABCabc";
string s5 = p;         // null-terminated string
string s6(p, 3);       // buffer/length

Typecasts

#include 

class string {
    operator (const char*)() const;
}

A string object can be assigned to a variable or passed as an actual parameter of type const char* implicitly (by default). Such assignments should be used carefully, since the library does not keep track of whether a char pointer refers to the given string buffer. To make sure that a char pointer refers to a valid string buffer, always make the scope of a char pointer variable smaller than or equal to the scope of a string object. In most cases passing a string object to a system or API call is safe (see examples below). This typecast operator does not perform any actions and simply returns a pointer to the string buffer.

The value of the char pointer is guaranteed to be non-NULL. Even if the string is empty, the char pointer will refer to a null-symbol.

A string buffer can not be modified through a constant char pointer. If you want to modify the string buffer through a char pointer, use unique(string&) function instead. This function always returns a reference to a unique string buffer (i.e. when the reference count is 1).

Compatibility note: MSVC and GCC may treat type casts in different ways when passing a string object to a function that takes (...) parameters, e.g. printf() or outstm::putf(). You should explicitly instruct the compiler to cast the string object to (const char*) to avoid this problem. PTypes provides a shorter typedef pconst for this.

Examples:

void assignment_example()
{
   string s = "abcdef";
   const char* p = s;
   // do string manipulation here...
}

void function_call_example()
{
   string s = "abcdef";
   puts(s);
   printf("%s\n", pconst(s));
}

Manipulation

Conversion

Created: 10 years 9 months ago
by Natalie Adams

Updated: 10 years 9 months ago
by Natalie Adams

Old Revisions

Page rendered in 0.06048s using 26 queries.