The C++ language, like Delphi, uses the reserved word class to create a new class:
class ClassName { field_1; field_n; }; class TAnimal { char Name[20]; long Age; bool Hungry; };
The difference between the C++ TAnimal class and the TAnimal class we created earlier in Delphi is that we cannot use the Name, Age, and Hungry fields of the C++ TAnimal class automatically. If you create an instance of the TAnimal class and try to access any of its properties, the compiler will refuse to compile your code:
TAnimal an; an.Age = 2; // TAnimal::Age is not accessible
The reason you cannot access these fields is visibility. In Delphi, fields are public by default, which means that any code that can use the object can access its fields. In C++, fields are private by default, which means that they can only be accessed inside the methods of the class. Even if a piece of code can use the object, it cannot use its private fields.
In order to have the C++ TAnimal class behave like the Delphi TAnimal class, we have to make these fields public by storing them in the public section of the class. This simply involves writing them after the reserved word public followed by a colon (public:), which denotes the beginning of the public section in a C++ class:
class TAnimal { public: char Name[20]; long Age; bool Hungry; };
After you've made the fields public, you'll be able to access these fields in TAnimal objects, as shown in Listing 10-7.
Listing 10-7: Accessing the public fields of the TAnimal class
#include <iostream.h> #include <conio.h> #pragma hdrstop class TAnimal { public: char Name[20]; long Age; bool Hungry; }; #pragma argsused int main(int argc, char* argv[]) { TAnimal an; // create an instance of the TAnimal class strcpy(an.Name, "ant"); an.Age = 1; an.Hungry = true; getch(); return 0; }
To make the C++ TAnimal class work like the Delphi TAnimal class, we still have to do one more thing — create the ShowInfo method for displaying the object data on screen.
To add a method to a C++ class, you have to add the method's header to the public section of the class and write the method's implementation outside the class (in C++ you can also write the method's implementation inside the class block, as you'll see shortly).
Here's how to implement a new method in a C++ class:
class ClassName { return_type MethodName(parameters); }; return_type ClassName::MethodName(parameters) { method_implementation; }
Listing 10-8 shows how to add the ShowInfo method to the TAnimal class.
Listing 10-8: The complete C++ TAnimal class
#include <iostream.h> #include <conio.h> #pragma hdrstop class TAnimal { public: char Name[20]; long Age; bool Hungry; void ShowInfo(); }; void TAnimal::ShowInfo() { // declare and initialize an array of strings char* HUNGRY_STRING[] = { {"No"}, {"Yes"} }; cout << "Name: " << Name << endl; cout << "Age: " << Age << endl; cout << "Hungry: " << HUNGRY_STRING[Hungry] << endl; } #pragma argsused int main(int argc, char* argv[]) { TAnimal an; strcpy(an.Name, "ant"); an.Age = 1; an.Hungry = true; an.ShowInfo(); getch(); return 0; }
The this pointer is the C++ equivalent of the Delphi Self pointer. You can use the this pointer in methods to access the object in which the method is called:
void TAnimal::ShowInfo() { char* HUNGRY_STRING[] = { {"No"}, {"Yes"} }; cout << "Name: " << this->Name << endl; cout << "Age: " << this->Age << endl; cout << "Hungry: " << HUNGRY_STRING[this->Hungry] << endl; } int main(int argc, char* argv[]) { TAnimal animal1; strcpy(animal1.Name, "one"); animal1.ShowInfo(); // this in ShowInfo() = animal1 TAnimal animal2; strcpy(animal2.Name, "two"); animal2.ShowInfo(); // this in ShowInfo() = animal2 return 0; }
In both Delphi and C++, standard functions and procedures can be marked with the inline directive to tell the compiler to try to optimize the code. To reduce typing, C++ allows you to add inline methods by simply writing the implementation of the method inside the class block:
class ClassName { return_type InlinedMethod(parameters) { method_implementation; } };
The following listing shows an updated version of the TAnimal class that has two new methods: Eat and Eat2. These methods illustrate how you can add inline methods to a C++ class.
Listing 10-9: Inline methods
class TAnimal { public: char Name[20]; long Age; bool Hungry; void ShowInfo(); void Eat() { Hungry = false; } void Eat2(); }; inline void TAnimal::Eat2() { Hungry = false; }
In Delphi, a class can be stored in one unit, with the class interface in the interface section and the method implementations in the implementation section. In C++, you have to store the class interface in a header file, and the method implementations in a .cpp source file. You must also include the class header file in its source file to connect the two files. Listings 10-10A and
10-10B show the Animal.h and the Animal.cpp files that make up the TAnimal class.
Listing 10-10A: The Animal.h file
class TAnimal { public: char Name[20]; long Age; bool Hungry; void ShowInfo(); /* inline method */ void Eat() { Hungry = false; } void Eat2(); };
Listing 10-10B: The Animal.cpp file
#include <iostream.h> // for cout #pragma hdrstop #include "Animal.h" inline void TAnimal::Eat2() { Hungry = false; } void TAnimal::ShowInfo() { // declare and initialize an array of strings char* HUNGRY_STRING[] = { {"No"}, {"Yes"} }; cout << "Name: " << Name << endl; cout << "Age: " << Age << endl; cout << "Hungry: " << HUNGRY_STRING[Hungry] << endl; }
To derive a new class from an existing class in C++, use the following syntax:
class NewClass: ExistingClass { }; class TBird: TAnimal { };
When you declare a new class from an existing one using the above syntax, you won't get the same results as you do in Delphi. In Delphi, when you derive a new class from an existing one, you'll automatically be able to access all fields that are publicly visible in the original class. In C++, all fields will be treated as private, no matter what their visibility in the ancestor class is. To retain original field visibility, use the following syntax to derive a new class in C++:
class NewClass: public ExistingClass { }; class TBird: public TAnimal { };