Polymorphism and Abstraction

 Polymorphism

In an inheritance scenario, a parent class is configured to provide its child with the basic foundation the child needs. Although a child can implement a new behavior not available on the parent object, sometimes a child object will need a customized implementation of a behavior that has already been configured with its parent. That is what happens for example when inheriting a sphere from a circle class. Both have a characteristic called Area but the area is calculated differently on each shape.

 Inheritance Review
1. Create a new C++ Console Application in a folder called Polymorphism
2. Save the first file as Main and the project as Polymorphism
3. Add a new class and save it as Circle
4. Create a TCircle class in the Circle.h file as follows:

 //--------------------------------------------------------------------------- #ifndef CircleH #define CircleH //--------------------------------------------------------------------------- class TCircle { public: TCircle(double r = 0.00); ~TCircle(); void setRadius(const double r) { Radius = r; } double getRadius() const { return Radius; } double Area() const; void ShowCharacteristics() const; protected: double Radius; }; //--------------------------------------------------------------------------- #endif
5. Implement the TCircle class in the Circle.cpp file as follows:

 //--------------------------------------------------------------------------- #include using namespace std; #include "Circle.h" //--------------------------------------------------------------------------- const double PI = 3.14159; //--------------------------------------------------------------------------- TCircle::TCircle(double r) : Radius(r) { } //--------------------------------------------------------------------------- TCircle::~TCircle() { } //--------------------------------------------------------------------------- double TCircle::Area() const { return Radius * Radius * PI; } //--------------------------------------------------------------------------- void TCircle::ShowCharacteristics() const { cout << "Circle Characteristics";  cout << setiosflags(ios::fixed) << setprecision(2); cout << "\nRadius: " << getRadius(); cout << "\nArea: " << Area(); } //---------------------------------------------------------------------------
6. Add a new class and save it as Sphere
7. To create a new TSphere class based on the TCircle class, lay its foundation in the Sphere.h file as follows:

 //--------------------------------------------------------------------------- #ifndef SphereH #define SphereH #include "Circle.h" //--------------------------------------------------------------------------- class TSphere : public TCircle { public: TSphere(double x); ~TSphere() {} double Area() const; double Volume() const; void ShowCharacteristics() const; private: }; //--------------------------------------------------------------------------- #endif
8. Implement the new class as follows:

 //--------------------------------------------------------------------------- #include using namespace std; #include "Sphere.h" //--------------------------------------------------------------------------- const double PI = 3.14159; //--------------------------------------------------------------------------- TSphere::TSphere(double n) : TCircle(n) { } //--------------------------------------------------------------------------- double TSphere::Area() const { return 4 * PI * Radius * Radius; } //--------------------------------------------------------------------------- double TSphere::Volume() const { return 4 * PI * Radius * Radius * Radius / 3; } //--------------------------------------------------------------------------- void TSphere::ShowCharacteristics() const { cout << "Circle Characteristics";  cout << setiosflags(ios::fixed) << setprecision(2); cout << "\nRadius: " << getRadius(); cout << "\nArea: " << Area(); cout << "\nVolume: " << Volume(); } //---------------------------------------------------------------------------
9. To inherit another class, add a new class and save it as Cylinder
10. Create the TCylinder class based on TCircle in the Cylinder.h file as follows:

 //--------------------------------------------------------------------------- #ifndef CylinderH #define CylinderH #include "Circle.h" //--------------------------------------------------------------------------- class TCylinder : public TCircle { public: TCylinder(double r, double h); ~TCylinder() {} void setHeight(const double h) { Height = h; } double getHeight() const { return Height; } double BaseArea() const; double LateralArea() const; double Area() const; double Volume() const; void ShowCharacteristics() const; private: double Height; }; //--------------------------------------------------------------------------- #endif
11. Implement the new class in its source file as follows:

 //--------------------------------------------------------------------------- #include using namespace std; #include "Cylinder.h" //--------------------------------------------------------------------------- const double PI = 3.14159; //--------------------------------------------------------------------------- TCylinder::TCylinder(double x, double y) : TCircle(x), Height(y) { } //--------------------------------------------------------------------------- double TCylinder::BaseArea() const { return TCircle::Area(); } //--------------------------------------------------------------------------- double TCylinder::LateralArea() const { double Circ = Radius * 2 * PI; return Circ * Height; } //--------------------------------------------------------------------------- double TCylinder::Area() const { double Base = TCircle::Area(); double Lateral = LateralArea(); return (2 * Base) + Lateral; } //--------------------------------------------------------------------------- double TCylinder::Volume() const { double Base = TCircle::Area(); return Base * Height; } //--------------------------------------------------------------------------- void TCylinder::ShowCharacteristics() const {  cout << "Circle Characteristics"; cout << setiosflags(ios::fixed) << setprecision(2); cout << "\nRadius: " << getRadius(); cout << "\nHeight: " << getHeight(); cout << "\nBase Area: " << BaseArea(); cout << "\nLateral Area: " << LateralArea(); cout << "\nArea: " << Area(); cout << "\nVolume: " << Volume(); } //---------------------------------------------------------------------------
12. To prepare a test, change the main() function in the Main.cpp file as follows:

 //--------------------------------------------------------------------------- #include using namespace std; //--------------------------------------------------------------------------- #include "Circle.h" #include "Sphere.h" #include "Cylinder.h" int main(int argc, char* argv[]) { TCircle e(12.55); TSphere s(22.25); TCylinder c(34.05, 28.35); e.ShowCharacteristics(); cout << "\n\n"; s.ShowCharacteristics(); cout << "\n\n"; c.ShowCharacteristics(); return 0; } //---------------------------------------------------------------------------
13. To test the program, press F9.
14. We can also dynamically declare the objects and access them as pointers. To see an example, change the main() function as follows:

 //--------------------------------------------------------------------------- #include using namespace std; //--------------------------------------------------------------------------- #include "Circle.h" #include "Sphere.h" #include "Cylinder.h" int main(int argc, char* argv[]) { TCircle *e = new TCircle(12.55); TSphere *s = new TSphere(16.15); TCylinder *c = new TCylinder(14.25, 10.85); e->ShowCharacteristics(); cout << "\n\n"; s->ShowCharacteristics(); cout << "\n\n"; c->ShowCharacteristics(); return 0; } //---------------------------------------------------------------------------
15. Test the program.

When studying inheritance, we learned that there is a special bond between an inherited class and its parent. Not only does the child object have access to the public members of a class but also the child, based on this relationship, has direct access to the members of the protected section (the child is a protégé) of the parent. The program above shows us that, in order to access a class’ members, we can just declare an instance of the class and use either the member access operator “.” or the pointer access operator “->”.

If there is such a good relationship between a class and its children, is it possible to access a member of a child object using an instance of the parent? We will declare only an instance of the parent class, TCircle, and try to access its child using such a variable.
16. Change the main() function as follows:

 //--------------------------------------------------------------------------- #include using namespace std; //--------------------------------------------------------------------------- #include "Circle.h" #include "Sphere.h" #include "Cylinder.h" int main(int argc, char* argv[]) { TSphere *s = new TSphere(15.32); TCylinder *c = new TCylinder(36.08, 20.24); TCircle *e = s; e->ShowCharacteristics(); cout << "\n\n"; e = c; e->ShowCharacteristics(); return 0; } //---------------------------------------------------------------------------
17. Test the program.
Notice that, although the pointer variable *e has been initialized with variables *s and *c, only the characteristics of the circle are displayed.
 Virtual Functions

A virtual function is a function that makes sure that, in an inheritance scenario, the right function is called regardless of the expression that calls the function. The last three classes we have used have two functions called Area() and ShowCharacteristics() each. Let us consider the member function ShowCharacteristics() that is present in all three classes. If we need an instance of the parent class to call the right member function, in this case Area, we must declare ShowCharacteristics () in the parent class as virtual.

 Declaring a Virtual Function
1. Click the Circle.h tab and change the declaration of the Area() function as follows:

 //--------------------------------------------------------------------------- #ifndef CircleH #define CircleH //--------------------------------------------------------------------------- class TCircle { public: TCircle(double r = 0.00); ~TCircle(); void setRadius(const double r) { Radius = r; } double getRadius() const { return Radius; } double Area() const; virtual void ShowCharacteristics() const; protected: double Radius; }; //--------------------------------------------------------------------------- #endif
2. Test the program again. Notice that, this time, even though an instance of the TCircle class made the call, the characteristics of the assigned variables display.
4. Since the Area() function is present on the parent as well as the inherited classes, make it virtual in the base class as follows:

 //--------------------------------------------------------------------------- #ifndef CircleH #define CircleH //--------------------------------------------------------------------------- class TCircle { public: TCircle(double r = 0.00); ~TCircle(); void setRadius(const double r) { Radius = r; } double getRadius() const { return Radius; } virtual double Area() const; virtual void ShowCharacteristics() const; protected: double Radius; }; //--------------------------------------------------------------------------- #endif
5. Test the program. Notice that the right functions, as far as their having been assigned to the base class instance goes, are called.
Even though you can use polymorphism to help the compiler identify which function is being called, if you want to access the same function of the base class, you can qualify it with the scope resolution operator “::”.

As you can see, a function with the same name can be declared in both a base and a derived classes. This allows a derived class to define its custom definition of the function. Because the derived class “re-writes” the same function, the derived class is said to override the function. A function can be overridden only if it is virtual. A function can be virtual only if carries the same name, the same return type, and the same type(s) of argument(s) if any.
 Virtual Destructors

Consider a case where you have created a class that is derived from another class. When you dynamically call the inherited class using an instance of the base class (as done in the last example), during the closing of the program, the destructor of the child class is called first, followed by the destructor of the base class. If you dynamically declare an instance of the base class and then invoke the children of the class, you need to make sure that each destructor and the right destructor of the classes that was used is called to destroy the class; this is safe measure to avoid memory leak. This aspect of C++ programming is taken care of by declaring the destructor of the base class as virtual. Whenever the destructor of the parent class is declared virtual, the destructor of an inherited class is also virtual. This ensures that, the program closes, all of the destructors of the base class and its children that were used are called, providing a safe claim of the memory that was used.

To declare a destructor as virtual, type the virtual keyword on its left, in the body of the class. Here is an example:

 //--------------------------------------------------------------------------- #ifndef CircleH #define CircleH //--------------------------------------------------------------------------- class TCircle { public: TCircle(double r = 0.00); virtual ~TCircle(); void setRadius(const double r) { Radius = r; } double getRadius() const { return Radius; } double Area() const; virtual void ShowCharacteristics() const; protected: double Radius; }; //--------------------------------------------------------------------------- #endif
 Abstract Classes

An abstract class is a class whose role is only meant to lay a foundation for those classes that would need a common behavior or similar characteristics. Therefore, an abstract class is used only as a base class for inheritance. A class is made abstract by declaring at least one its member functions as a “pure” virtual function.

Only a virtual function can be made “pure”. The syntax of declaring a pure function is:

 virtual ReturnType FunctionName() = 0;

The virtual keyword is required to make sure that a (any) child of this class can implement this function as it deems fit. The ReturnType is the data type that the function will return. The FunctionName is an appropriate name for the function. The = 0 is required. It lets the compiler know that this function is a pure virtual function.

When a function has been declared as pure virtual, you do not need to implement it. Instead, each inherited class of an abstract class must provide its own implementation of the pure member function.

When creating an abstract class, you can declare all of its member functions as pure. Here is an example:

 //--------------------------------------------------------------------------- struct TTent { virtual int WhatIsTheCapacity() = 0; virtual double TentArea() = 0; virtual double TentVolume() = 0; virtual char* TextureColor() = 0; }; //---------------------------------------------------------------------------

In this case, the class does not need a source file or any implementation because none of its member functions will be implemented.

An abstract base class can also have a mix of pure and non-pure functions. Here is an example:

 //--------------------------------------------------------------------------- struct TTent { virtual int WhatIsTheCapacity() = 0; virtual double TentArea() = 0; virtual double TentVolume() = 0; virtual char* TextureColor() = 0; // Pure virtual function virtual char* TextureName(); // Virtual function int ShapeType(); // Regular member function }; //---------------------------------------------------------------------------

In this case, as we have done with the other classes so far, you must implement the non-pure functions in the base and let the inherited classes implement their own version(s) of the pure virtual function(s).

 Implementing Abstract Classes
1. Create a new C++ Console Application and save it in a folder called Polygons
2. Save the class as Main and the project as RegPolygons
3. Add a new class and save it as Polygon
4. On the Status Bar, click the Polygon.h tab and create a regular class as follows:

 //--------------------------------------------------------------------------- #ifndef PolygonH #define PolygonH //--------------------------------------------------------------------------- namespace Shapes { class TPolygon { public: TPolygon(int s = 0, char *n = "", double r = 0.00); virtual ~TPolygon(); void setNbrOfSides(const int n); int getNbrOfSides() const { return NbrOfSides; } void setPolyName(const char *n); char * getPolyName() const { return PolyName; } void setRadius(const double r); double getRadius() const { return Radius; } double CentralAngle() const; double InteriorAngle() const; protected: int NbrOfSides; char *PolyName; double Radius; }; } //--------------------------------------------------------------------------- #endif
5. Click the Polygon.cpp tab and implement the member functions as follows:

6. Prepare the main() function for a test as follows:

 //--------------------------------------------------------------------------- #include #include using namespace std; //--------------------------------------------------------------------------- #include "Polygon.h" int main(int argc, char* argv[]) { Shapes::TPolygon *Pol = new Shapes::TPolygon; Pol->setRadius(15.55); Pol->setNbrOfSides(25); Pol->setPolyName("Unknown"); cout << "Shape Characteristics"; cout << setiosflags(ios::fixed) << setprecision(2); cout << "\nName: " << Pol->getPolyName(); cout << "\nSides: " << Pol->getNbrOfSides(); cout << "\nRadius: " << Pol->getRadius(); cout << "\nCentral Angle: " << Pol->CentralAngle() << "*"; cout << "\nInterior Angle: " << Pol->InteriorAngle(); return 0; } //---------------------------------------------------------------------------
8. To add some pure virtual function and qualify the class as abstract, change the TPolygon class creation as follows:

 //--------------------------------------------------------------------------- #ifndef PolygonH #define PolygonH //--------------------------------------------------------------------------- namespace Shapes { class TPolygon { public: TPolygon(int s = 0, char *n = "", double r = 0.00); virtual ~TPolygon(); void setNbrOfSides(const int n); int getNbrOfSides() const { return NbrOfSides; } void setPolyName(const char *n); char * getPolyName() const { return PolyName; } void setRadius(const double r); double getRadius() const { return Radius; } double CentralAngle() const; double InteriorAngle() const; virtual double Side() = 0; virtual double Apothem() = 0; virtual double Perimeter() = 0; double Area(); virtual void ShapeCharacteristics() = 0;  protected: int NbrOfSides; char *PolyName; double Radius; }; } //--------------------------------------------------------------------------- #endif
9. To implement the newly added Area() member function, add it to the Polygon.cpp file as follows:

 //--------------------------------------------------------------------------- #include using namespace std; #include "Polygon.h" //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- namespace Shapes { TPolygon::TPolygon(int s, char *n, double r) { . . . } //--------------------------------------------------------------------------- . . . //--------------------------------------------------------------------------- double TPolygon::Area() { double p = Perimeter(); double r = Apothem(); return p * r / 2; } //--------------------------------------------------------------------------- } //---------------------------------------------------------------------------
10. To test the program, press F9.
11. Read the errors that you receive. As you can see, you are not allowed to declare an instance of an abstract class:
13. Add a new class and save it as Triangle
14. In the Triangle.h file, derive a new TTriangle class from the TPolygon class as follows:

 //--------------------------------------------------------------------------- #ifndef TriangleH #define TriangleH #include "Polygon.h" //--------------------------------------------------------------------------- class TTriangle : public Shapes::TPolygon { public: // We use two constructors so that the user can initialize // either by not specifying anything or by providing the radius TTriangle(); TTriangle(double r); ~TTriangle(); virtual double Side(); virtual double Apothem(); virtual double Perimeter(); double Height(); virtual void ShapeCharacteristics(); protected: private: }; //--------------------------------------------------------------------------- #endif
15. Implement the class in the Triangle.cpp source file as follows:

 //--------------------------------------------------------------------------- #include #include #include using namespace std; #include "Triangle.h" //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- TTriangle::TTriangle() { // If the constructor is empty, at least we know the number of sides // and the name of this polygon setNbrOfSides(3); setPolyName("Equilateral Triangle"); setRadius(getRadius()); } //--------------------------------------------------------------------------- TTriangle::TTriangle(double r) { setNbrOfSides(3); setPolyName("Equilateral Triangle"); setRadius(r); } //--------------------------------------------------------------------------- TTriangle::~TTriangle() { } //--------------------------------------------------------------------------- double TTriangle::Side() { return Radius * sqrt(3); } //--------------------------------------------------------------------------- double TTriangle::Apothem() { return Radius / 2; } //--------------------------------------------------------------------------- double TTriangle::Perimeter() { double S = Side(); return 3 * S; } //--------------------------------------------------------------------------- double TTriangle::Height() { return Apothem() + Radius; } //--------------------------------------------------------------------------- void TTriangle::ShapeCharacteristics() { cout << "Shape Characteristics"; cout << "\nName: " << getPolyName(); cout << "\nSides: " << getNbrOfSides(); cout << "\nRadius: " << getRadius(); cout << "\nCentral Angle: " << CentralAngle(); cout << "\nInterior Angle: " << InteriorAngle(); cout << setiosflags(ios::fixed) << setprecision(2); cout << "\nApothem: " << Apothem(); cout << "\nHeight: " << Height(); cout << "\nPerimeter: " << Perimeter(); cout << "\nArea: " << Area(); } //---------------------------------------------------------------------------
16. To prepare a test, change the Main.cpp file as follows:

 //--------------------------------------------------------------------------- #include using namespace std; //--------------------------------------------------------------------------- #include "Triangle.h" int main(int argc, char* argv[]) { TTriangle *Tri = new TTriangle; Tri->setRadius(15.55); Tri->ShapeCharacteristics(); return 0; } //---------------------------------------------------------------------------
18. Add a new class and save it as Square
19. In the Square.h file, create a regular polygon of a square based on the TPolygon class as follows:

 //--------------------------------------------------------------------------- #ifndef SquareH #define SquareH #include "Polygon.h" //--------------------------------------------------------------------------- class TPolySquare : public Shapes::TPolygon { public: TPolySquare(); TPolySquare(double r); ~TPolySquare() {} virtual double Side(); virtual double Apothem(); virtual double Perimeter(); virtual void ShapeCharacteristics(); protected: private: }; //--------------------------------------------------------------------------- #endif
20. Implement the TPolySquare class as follows:

 //--------------------------------------------------------------------------- #include #include #include using namespace std; //--------------------------------------------------------------------------- #include "Square.h" //--------------------------------------------------------------------------- TPolySquare::TPolySquare() { // If the constructor is empty, at least we know the number of sides // and the name of this polygon setNbrOfSides(4); setPolyName("Square"); setRadius(getRadius()); } //--------------------------------------------------------------------------- TPolySquare::TPolySquare(double r) { setNbrOfSides(4); setPolyName("Square"); setRadius(r); } //--------------------------------------------------------------------------- double TPolySquare::Side() { return Radius * sqrt(2); } //--------------------------------------------------------------------------- double TPolySquare::Apothem() { return sqrt(2) * Radius / 2; } //--------------------------------------------------------------------------- double TPolySquare::Perimeter() { double S = Side(); return 4 * S; } //--------------------------------------------------------------------------- void TPolySquare::ShapeCharacteristics() { cout << "Shape Characteristics"; cout << "\nName: " << getPolyName(); cout << "\nSides: " << getNbrOfSides(); cout << "\nRadius: " << getRadius(); cout << setiosflags(ios::fixed) << setprecision(0); cout << "\nCentral Angle: " << CentralAngle(); cout << "\nInterior Angle: " << InteriorAngle(); cout << setiosflags(ios::fixed) << setprecision(2); cout << "\nApothem: " << Apothem(); cout << "\nPerimeter: " << Perimeter(); cout << "\nArea: " << Area(); } //---------------------------------------------------------------------------
21. Add a new class and save it as Hexagon
22. Create a THexagon object derived from the TPolygon class as follows:

 //--------------------------------------------------------------------------- #ifndef HexagonH #define HexagonH #include "Polygon.h" //--------------------------------------------------------------------------- class THexagon : public Shapes::TPolygon { public: THexagon(); THexagon(double r); ~THexagon() {} virtual double Side(); virtual double Apothem(); virtual double Perimeter(); virtual void ShapeCharacteristics(); protected: private: }; //--------------------------------------------------------------------------- #endif
23. Implement the THexagon class as follows:

 //--------------------------------------------------------------------------- #include #include #include using namespace std; #include "Hexagon.h" //--------------------------------------------------------------------------- THexagon::THexagon() { // If the constructor is empty, at least we know the number of sides // and the name of this polygon setNbrOfSides(6); setPolyName("Hexagon"); setRadius(getRadius()); } //--------------------------------------------------------------------------- THexagon::THexagon(double r) { setNbrOfSides(6); setPolyName("Hexagon"); setRadius(r); } //--------------------------------------------------------------------------- double THexagon::Side() { return Radius; } //--------------------------------------------------------------------------- double THexagon::Apothem() { return sqrt(3) * Radius / 2; } //--------------------------------------------------------------------------- double THexagon::Perimeter() { double S = Side(); return 6 * S; } //--------------------------------------------------------------------------- void THexagon::ShapeCharacteristics() { cout << "Shape Characteristics"; cout << "\nName: " << getPolyName(); cout << "\nSides: " << getNbrOfSides(); cout << "\nRadius: " << getRadius(); cout << setiosflags(ios::fixed) << setprecision(0); cout << "\nCentral Angle: " << CentralAngle(); cout << "\nInterior Angle: " << InteriorAngle(); cout << setiosflags(ios::fixed) << setprecision(2); cout << "\nApothem: " << Apothem(); cout << "\nPerimeter: " << Perimeter(); cout << "\nArea: " << Area(); } //---------------------------------------------------------------------------
24. Before testing the program, change the Main.cpp file as follows:

 //--------------------------------------------------------------------------- #include using namespace std; //--------------------------------------------------------------------------- #include "Triangle.h" #include "Square.h" #include "Hexagon.h" //--------------------------------------------------------------------------- int main(int argc, char* argv[]) { TTriangle *Tri = new TTriangle; Tri->setRadius(15.55); Tri->ShapeCharacteristics(); cout << "\n\nNew Shape"; TPolySquare *Sq = new TPolySquare(22.36); Sq->ShapeCharacteristics(); cout << "\n\nNew Shape"; clrscr(); THexagon *Hx = new THexagon; Hx->setRadius(36.08); Hx->ShapeCharacteristics(); return 0; } //---------------------------------------------------------------------------

 Value Casting

 Introduction
 We have been introduced to declaring variables using specific data types. After declaring a value and initializing it, you may want the value to change type without redefining it. This is required in some cases where you already have a value, probably produced by one variable, while another variable declared with a different data type. This means that you would need to convert a value from one type into another type. For example, you may have declared a variable using a double data type but you need the value of that variable to be used as an int. Transferring a value from one type to another is referred to as casting. There are two broad types of casting available in C++: C's old school of casting and the C++ standards.

 C How To Cast a Value
 C, the parent of C++ supports value casting by specifying the type of value you want an existing one to have. To do this, you use the following formula: (DataType)Expression Based on this formula, in the parentheses, enter the type of data you want the existing or resulting value to have. The DataType factor can be any of the data types we saw above. The Expression factor can be a constant value. Here is an example: #include using namespace std; int main() { cout << "Number: " << (int)3.14159 << "\n"; return 0; } Notice that the value to convert is a floating-point number. If the conversion is successful, the new value would be conform to the type in parentheses. For example, the above code would produce: Number: 3 Here is another version of the above program: #include using namespace std; int main() { int number; number = (int)3.14159; cout << "Number: " << number << "\n"; return 0; } The Expression factor can also be the result of a calculation. In this case, you should include the whole expression is its own parentheses. The Expression factor of our formula can also be the name of a variable that holds a value. Here is an example: #include using namespace std; int main() { double price = 258.85; int number; cout << "Price? \$" << price << "\n"; number = (int)price; cout << "Number: " << number << "\n"; return 0; } This would produce: Price? \$258.85 Number: 258

 C++ Casting
 C++ provides its own support of value casting using variable keywords so you can specify the type of conversion you want. One of the keywords used is static_cast and the formula is: static_cast(Expression) In this formula, the static_cast keyword, the <, the >, and the parentheses are required. The DataType factor should be an existing data type such as those we have reviewed in this lesson. The Expression factor can be a constant value. Here is an example that converts a floating-point number to an integer: #include using namespace std; int main() { cout << "Number: " << static_cast(3.14159) << "\n"; return 0; } You can also assign the resulting value to a variable before using it: #include using namespace std; int main() { int number = static_cast(3.14159); cout << "Number: " << number << "\n"; return 0; } The value to convert can also be the result of a calculation. The value can also be originating from an existing variable whose value you want to convert to a new type. Here is an example: #include using namespace std; int main() { double PI = 3.14159; int number; number = static_cast(PI); cout << "PI = " << PI << endl; cout << "Number = " << number << "\n"; return 0; } This would produce: PI = 3.14159 Number = 3

 Variable Scope

 Introduction
 In the previous lesson, to declare a variable, we proceeded inside of the main() function. Such a variable could be used only inside of the square brackets of main(). In some cases, you may want to declare a variable that can be accessed from one section of the code. The section of code in which a variable can be accessed is referred to as its scope.
 Local Variables
 If you declare a variable inside of a function such as main(), that function can be accessed only from that function. Consider the following example: #include using namespace std; int main() { double number = 3.14159; cout << "Number = " << number << "\n"; return 0; } Such a variable is referred to as local because it is declared in a function. In reality, a local scope is defined by a beginning opening curly bracket "{" and a closing curly bracket "}". Everything between these brackets belongs to a local scope. Once you have declared such a variable, you cannot declare another variable in the same scope and that bears the same name. Consider the following example: #include using namespace std; int main() { double number = 3.14159; cout << "Number = " << number << "\n"; double number = 2.98; cout << "Number = " << number << "\n"; return 0; } This would produce a "redefinition" error and the program would not compile, even if the second declaration uses a different data type. As one type of solution to this kind of problem, C++ allows you to create a "physical" scope. To do this, you can use curly brackets to delimit the scope of a particular variable. Here is an example: #include using namespace std; int main() { { double number = 3.14159; cout << "Number = " << number << "\n"; } double number = 2.98; cout << "Number = " << number << "\n"; return 0; } This would produce: Number = 3.14159 Number = 2.98 In the code, notice that we delimit only the first declaration. Indeed, you can delimit each scope if you want: #include using namespace std; int main() { { double number = 3.14159; cout << "Number = " << number << "\n"; } { double number = 2.98; cout << "Number = " << number << "\n"; } return 0; }