Example 1 - Review of classes, constructors and destructors
// Review Example 1
#include <iostream>
#include <cstring>
#include <cctype>
using namespace std;
class Name
{
char* name_;
public:
Name();
Name(const char* name);
Name(const Name&);
~Name();
const char* get_name() const { return name_ ? name_ : ""; }
void set_name(const char* name);
const char* firstName() const;
char* lastName() const;
};
Name::Name()
: name_(0)
{
}
Name::Name(const char* name)
: name_(new char[strlen(name)+1])
{
strcpy(name_,name);
}
Name::Name(const Name& other)
: name_(new char[strlen(other.name_)+1])
{
strcpy(name_,other.name_);
}
Name::~Name()
{
if (name_) {
delete[] name_;
name_ = 0;
}
}
void Name::set_name(const char* name)
{
delete[] name_;
name_ = new char[strlen(name)+1];
strcpy(name_,name);
}
const char* Name::firstName() const
{
const char* ptr = strchr(name_,',');
if (!ptr) {
return name_;
}
// skip over whitespace text
while (ptr) {
if (isalpha(*ptr))
break;
else
++ptr;
}
return ptr;
}
char* Name::lastName() const
{
static char* ptr = 0;
if (ptr) {
delete [] ptr;
}
ptr = new char[strlen(name_)+1];
strcpy(ptr,name_);
strtok(ptr,",");
return ptr;
}
int main()
{
Name joe("Bentley, Joe");
Name john("Doe,John");
Name jane("Doe, Jane");
Name mary("Mary");
Name nobody;
Name clone(john);
cout << joe.get_name() << endl;
cout << john.firstName() << endl;
cout << jane.lastName() << endl;
cout << mary.get_name() << ' ' << mary.firstName() << ' ' << mary.lastName() << endl;
cout << nobody.get_name() << endl;
cout << clone.get_name() << endl;
}
Review Questions
- Is the default constructor necessary?
- Is the copy constructor necessary?
- How can you "avoid" writing the default constructor?
- Are the constructor initializers necessary?
- Can you write the default's constructor initializer as : name_("") ?
What are the ramifications?
- Why does the Name::firstName() return const char* and the Name::lastName() return char* ?
- Why does Name::get_name() return name_ ? name_ : "" and not just return name_ ?