TOC PREV NEXT INDEX

C++: A Dialog


8.10. Answers to Exercises


1. This one was a little tricky. I'll bet you thought that making the default constructor private would keep this from compiling, but it turns out that we're not using the default constructor. That should be obvious in the line string n("Test");, which clearly uses string::string(char* p), but what does the compiler do with the line string x = n;? You might think that it calls the default constructor to make x and then uses operator = to copy the value of n into it. If that were true, the private status of the default constructor would prevent the program from compiling. However, what actually happens is that the copy constructor string::string(const string&) is used to make a brand new string called x with the same value as n. So, in this case, the private access specifier on the default constructor doesn't get in the way.
2. The output of the compiler should look something like this:

STREX6.cpp:
Error E2247 STREX6.cpp 16: `string::string(char *)' is not accessible in function main()
*** 1 errors in Compile ***
This one is a bit tricky. The actual problem is that making the constructor string::string(char*) private prevents the automatic conversion from char* to string required for the string::operator = (const string&) assignment operator to work. As long as there is an accessible string::string(char*) constructor, the compiler will use that constructor to build a temporary string from a char* argument on the right side of an =. This temporary string will then be used by string::operator = (const string&) as the source of data to modify the string on the left of the =. However, this is not possible if the constructor that makes a string from a char* isn't accessible where it is needed.1
3. The new class interface is shown in Figure 8.39.
FIGURE 8.39. The string class interface file (from code\string6.h)
#ifndef STRING6_H
#define STRING6_H
#include <iostream>

class string
{
friend std::ostream& operator << (std::ostream& os, const string& Str);
friend std::istream& operator >> (std::istream& is, string& Str);

public:
string();
string(const string& Str);
string& operator = (const string& Str);
~string();

string(char* p);
short GetLength();
bool operator < (const string& Str);
bool operator == (const string& Str);
bool operator > (const string& Str);
bool operator >= (const string& Str);
bool operator <= (const string& Str);
bool operator != (const string& Str);

private:
short m_Length;
char* m_Data;
};
#endif

4. The implementations of the comparison operators are shown in Figures 8.40 through 8.43.
FIGURE 8.40. The string class implementation of operator > (from code\string6.cpp)
bool string::operator > (const string& Str)
{
short Result;
short CompareLength;

if (Str.m_Length < m_Length)
CompareLength = Str.m_Length;
else
CompareLength = m_Length;

Result = memcmp(m_Data,Str.m_Data,CompareLength);

if (Result > 0)
return true;

if (Result < 0)
return false;

if (m_Length > Str.m_Length)
return true;

return false;
}

FIGURE 8.41. The string class implementation of operator >= (from code\string6.cpp)
bool string::operator >= (const string& Str)
{
short Result;
short CompareLength;

if (Str.m_Length < m_Length)
CompareLength = Str.m_Length;
else
CompareLength = m_Length;

Result = memcmp(m_Data,Str.m_Data,CompareLength);

if (Result > 0)
return true;

if (Result < 0)
return false;

if (m_Length >= Str.m_Length)
return true;

return false;
}

FIGURE 8.42. The string class implementation of operator != (from code\string6.cpp)
bool string::operator != (const string& Str)
{
short Result;

if (m_Length != Str.m_Length)
return true;

Result = memcmp(m_Data,Str.m_Data,m_Length);

if (Result == 0)
return false;

return true;
}

FIGURE 8.43. The string class implementation of operator <= (from code\string6.cpp)
bool string::operator <= (const string& Str)
{
short Result;
short CompareLength;

if (Str.m_Length < m_Length)
CompareLength = Str.m_Length;
else
CompareLength = m_Length;

Result = memcmp(m_Data,Str.m_Data,CompareLength);

if (Result < 0)
return true;

if (Result > 0)
return false;

if (m_Length <= Str.m_Length)
return true;

return false;
}

5. The test program appears in Figure 8.44.
FIGURE 8.44. The test program for the comparison operators of the string class (code\strcmp.cpp)
#include <iostream>
#include "string6.h"
using std::cout;
using std::endl;

int main()
{
string x = "x";
string xx = "xx";
string y = "y";
string yy = "yy";

// testing <
if (x < x)
cout << "ERROR: x < x" << endl;
else
cout << "OKAY: x NOT < x" << endl;
if (x < xx)
cout << "OKAY: x < xx" << endl;
else
cout << "ERROR: x NOT < xx" << endl;
if (x < y)
cout << "OKAY: x < y" << endl;
else
cout << "ERROR: x NOT < y" << endl;

// testing <=
if (x <= x)
cout << "OKAY: x <= x" << endl;
else
cout << "ERROR: x NOT <= x" << endl;
if (x <= xx)
cout << "OKAY: x <= xx" << endl;
else
cout << "ERROR: x NOT <= xx" << endl;
if (x <= y)
cout << "OKAY: x <= y" << endl;
else
cout << "ERROR: x NOT <= y" << endl;

// testing >
if (y > y)
cout << "ERROR: y > y" << endl;
else
cout << "OKAY: y NOT > y" << endl;
if (yy > y)
cout << "OKAY: yy > y" << endl;
else
cout << "ERROR: yy NOT > y" << endl;
if (y > x)
cout << "OKAY: y > x" << endl;
else
cout << "ERROR: y NOT > x" << endl;

// testing >=
if (y >= y)
cout << "OKAY: y >= y" << endl;
else
cout << "ERROR: y NOT >= y" << endl;
if (yy >= y)
cout << "OKAY: yy >= y" << endl;
else
cout << "ERROR: yy NOT >= y" << endl;
if (y >= x)
cout << "OKAY: y >= x" << endl;
else
cout << "ERROR: y NOT >= x" << endl;

// testing ==
if (x == x)
cout << "OKAY: x == x" << endl;
else
cout << "ERROR: x NOT == x" << endl;
if (x == xx)
cout << "ERROR: x == xx" << endl;
else
cout << "OKAY: x NOT == xx" << endl;
if (x == y)
cout << "ERROR: x == y" << endl;
else
cout << "OKAY: x NOT == y" << endl;

// testing !=
if (x != x)
cout << "ERROR: x != x" << endl;
else
cout << "OKAY: x NOT != x" << endl;
if (x != xx)
cout << "OKAY: x != xx" << endl;
else
cout << "ERROR: x NOT != xx" << endl;
if (x != y)
cout << "OKAY: x != y" << endl;
else
cout << "ERROR: x NOT != y" << endl;

return 0;
}


1
By the way, in case you're wondering what char * means, it's the same as char*. As I've mentioned previously, I prefer the latter as being easier to understand, but they mean the same to the compiler.


www.steveheller.com
steve@steveheller.com
TOC PREV NEXT INDEX