Skip to main content

C++ Classes

Programming
C++ Programming 

Introduction to Splitting Class Files
definition
Class structure 

If an aspect of object-oriented programming is encapsulation, then why would we split our classes into separate files?  Why not keep it all in one if we wish to "encapsulate" all there is about the class?
Recall that a part of encapsulation is also data hiding.  Think about your car for a bit as we use it in an analogous way.  A car is a complex device that contains many different components.  You are able to operate your car without the need to understand the complexities of the internal combustion engine or the radio electronics.  You don't need that knowledge to be able to effectively operate the car.
Likewise, a programmer using your class files does not need to know how you have implemented your methods to achieve the functionality.  In fact, perhaps you have a proprietary algorithm for a spell checker that is really fast and you don't want anybody to know how it works.   Users of that class also don't need to know how you implemented the spellchecker.  They only need to know how to make use of it.   "How to make us of it" comes in the form of the methods and their signatures.  As long as a user knows how to call your methods and what to expect as a return value, if any, they can use your class in their application.
Structure
Example 
In the car analogy, the owner's manual is analogous to the method signatures.  It specifies what you can do to operate the car and how to interact with the car's "interface".  In the separation of class files, the header file (.h file), is analogous to the car's owner's manual.  It specifies what "interface" elements are available (methods), providing information on how to use them.   There are no implementation details in the header file just as there are no implementation details on the internal workings of your car's engine, in the owner's manual.

Header Files

C++
Header File
In C++, your code will often contain multiple class files.  As a review, recall that class files allow you to model real-world objects in your code, and they also provide a container for functionality and behavior of coding structures.

C++ applications typically consist of multiple files.  Each of these files in your application may use any or all of the class files that you define in your application.  If this is the case, that class file definition must be the same in each and every file that uses it.  In order to avoid the duplication of code, C++ uses the concept of a header file and the #include preprocessor directive.

In C++, the common practice is to create your classes as two separate files.  The header file, with a .h extension on the filename, is used to contain the declarations found in the class file.  Declarations include function prototypes and class constructors typically.   The actual implementation of the code that performs the processing, exists in the implementation file that has the .cpp or .c filename extension.

To illustrate an example, let's go back to one of the examples found in the Introduction to C++ course on edX by Microsoft.  In Module 4 we created functions that represented some common mathematical operations to calculate the power of a base raised to an exponent, calculate the sine of an angle, and finally one to calculate the average of values in an array.  For this example, we will start to focus on building our own math library.

In C++, there is an existing library called cmath.  This library contains many common mathematical functions and we can simply make use of cmath rather than create our own library, but the exercise of doing so will serve a couple of purposes in this course.  First, it will allow you to learn how to create class files with header files.  Next, you will learn how to deal with namespaces, which are covered later in this module, and finally, the culmination of the math functions that you will build will help to serve as a project for this course.
This sample code will provide a starter for you by demonstrating the use of header and implementation files for a class called Math with a function for calculating the value of a base raised to an exponent.  We'll call this function pow.

Math.h

    // Math.h
    // Header file for the Math class

    #pragma once

    // Math class definition
    static class Math
    {
        public:

        // given base and exponent, calculate value
        static int Math::pow(int base, int exp);

    };
Let's evaluate the code listings one at a time.  In the first section, Math.h, we see the header file for our Math class.  Outside of the comments we see a line that indicates #pragma once.  This is a preprocessor directive that tells the compiler to only include this header once, regardless of how many times it has been imported in the program.
Next we see the class definition, static class Math.  The static keyword needs a little explanation so let's get that out of the way first.  When we declare a class as static, it is an indicator that we do not have to instantiate the class to use it in our program.  For example, if Math were not static, before we could use it in our program, we would need to create an instance of it as shown here:

    Math math = new Math();
    math.pow(2, 8);

For the Math class that we are creating in this course, we will consider it to be a utility class and therefore we want it to be static so we don't have to create an instance each time we want to use functionality in that class.

Next, our class definition continues with the opening curly brace and then the keyword public:   Anything after the public: keyword is considered to be of public visibility.  That is, it can be called from other classes directly.

After public: we declare our function for generating the power of a base raised to an exponent.  Note that this method is also using the static designation.  In order to call the function from a static class, the function must also be static.

Note that the function contains no implementation details however.  We simply indicate the data types of the parameters that we expect to use with this function.  As a matter of fact, we don't even have to use parameter names in this declaration at all, simply using static int Math::pow(int, int); is sufficient as we only need to indicate the data types that are expected by the function.

The last key piece to note about this declaration of the Math class is that we end it with a semicolon after the closing curly brace.  Most new programmers have a tendency to forget this.  Microsoft Visual Studio automatically adds the semicolon for you and many newer IDEs may also do the same.
For more information , you can see:
C and C++ with Visual Studio: https://aka.ms/edx-dev210.2x-vs02

Implementation Files

Let's now look at the implementation file, the one with the .cpp extension and the file that contains the actual functionality.
Math.cpp

    #include "stdafx.h"
    #include "Math.h"

    int Math::pow(int base, int exp)
    {
        int result = 1;

        for (int i = 0; i < exp; i++)
        {
            result = result * base;
        }

        return result;
    }

MathTest.cpp

    // MathTest.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include "Math.h"
    #include <iostream>

    using namespace std;

    int main()
    {
        int result = Math::pow(2, 10);
    
        cout << result << endl;

        return 0;
    }

Let's evaluate the code listings one at a time.  In the first section we saw Math.h, the header file for our Math class.  In this section, we discuss the Math.cpp file.  This is the implementation file for the Math class.  
We open the class file with two #include statements.  One includes the stdafx header file and the second brings in the Math header file.  The stdafx.h file is the precompiled header directive that is used in Visual Studio but some other compilers also make use of it.  Next, we include Math.h because the compiler needs to know what functions are part of this class.  Recall the discussion about function prototypes.  These now exist in the header file and not in the .cpp file.

The rest of the class contains the implementation details for calculating the power function.  The function name looks a little different now.  Instead of just the function name, we are using Math::pow as the function name.  This is using the concept of a scope resolution operator (::).  There are a couple of uses for the scope resolution operator, and it will be covered again in the discussion on namespaces but, in this instance, it is required to call static members of the class.

The code in this function implements the functionality using a for loop to calculate the base raised to the exponent provided.  Also note that there is no semicolon at the end of the closing curly brace.

Finally, in MathTest.cpp we see our standard main() function that we use for testing purposes.  Some refer to this as a driver program used for testing our code.  In the main() function, declare an int variable called result and assign it the value that is returned from the pow function in Math.   Note the use of the scope resolution operator again (::) and that we did not create an instance of the Math class but simply called the function directly on the class itself.  This is an example of a static class in action.

So how exactly does the header file factor into our code?  It is a concise method of describing what the class is intended to do.  In other words, it provides a look into the functions that exist in a class without concerning ourselves with the implementation details of those methods.  It also provides us with a mechanism to help reduce coding bugs by having the compiler catch omissions and misuses of the class and its components.  However, once again think about declaring a class in your applications main file, the one that includes main().  In our sample code with the Math class, if we did not include the Math.h file directive in MathTest.cpp, then MathTest will have no knowledge of Math.cpp and the compiler will generate an error.  By placing the include directive in MathTest.cpp, the compiler will actually make a copy of the contents of Math.h inside MathTest.cpp, which will mean that the function declarations will be included, and the compiler will understand the Math class.
In this video you will understand  Header file  briefly..

Constructors and Destructors 

Class Constructors

Constructor
Execution sequence of constructors 

Let's now turn our attention to the concept of constructors and destructors in our classes.  The topic of constructors was covered briefly in the Introduction to C++ course but we'll offer a review here and expand on the topic of constructors in this lesson, adding in concepts around destructors.

A constructor is used to initialize data members of a class.  The format of a constructor, at its most basic level, is that it contains the same name as the class itself, has no return type, and may or may not contain a parameter list.  Constructors are also, almost always, public although you can have a private constructor for use within the class only.  Some developers create a private constructor that is called via a public constructor, for the purposes of initializing private aspects of a class.

Classes can have multiple constructors.  Constructors can be overloaded in the same way that functions can be overloaded.  If you don't create a constructor in your class file, the compiler will create a default constructor automatically that will initialize member variables to default values.  A class has one, and only one, default constructor.  If you do create a default constructor or any other constructor in your class, then the compiler will not create one.  This is an important consideration because if you require or want a default constructor as well as other constructors, then you MUST create your own default constructor.  The default constructor, if provided, is one that does not have any parameters such as:

    class Person
    {
    public:
        Person();
        ~Person();
    };

This code sample demonstrates the template that is provided in Microsoft Visual Studio when creating a new C++ class.  It completes the template with a very simple class definition that includes the class name (Person) and two public members, the default constructor (Person();) and the destructor (~Person();).  Destructors will be covered in the topic on destructors.

There are actually two more, equally important, reasons for defining a default constructor in your classes.  First off, compound types (arrays or pointers) that may be defined inside a code block, can have undefined values when initialized to their default values.  You should ensure that these members are initialized correctly by creating your own default constructor and performing the initialization yourself.

The second reason is a little more complex and arises when your class contains a member that is a class itself.  The compiler's default constructor is unable to initialize that member.

The following code sample demonstrates the use of three different constructors, one default constructor, one that accepts two arguments and one that accepts three arguments.

**Person.h**

    #pragma once
    
    #include <string>
    
    class Person
    {
    
    private:
        std::string firstName;
        std::string lastName;
    
        int age;
    
    public:
        Person();
    
        Person(std::string fName, std::string lName);
    
        Person(std::string fName, std::string lName, int age);
    
        ~Person();

        void SayHello();
    };

**Person.cpp**


    #include "stdafx.h"
    #include "Person.h"
    #include <iostream>
    
    Person::Person()
    {
    
    }
    
    Person::Person(std::string fName, std::string lName)
    {
        firstName = fName;
        lastName = lName;
    }
    
    Person::Person(std::string fName, std::string lName, int age)
    {
        firstName = fName;
        lastName = lName;
    
        age = age;
    }
    
    
    Person::~Person()
    {
    }

The first constructor is the default constructor.  It has no parameters and because we have not initialized our private member variables, this constructor will do so with the default values for data types of those member variables.

The second constructor takes two arguments and uses those to initialize the first and last name member variables in the class.  Here is where you need to do a little research on the compiler you are using to determine how the age variable will be initialized.  The reason is, because we do not initialize age in the class when we declared it and because this constructor does not initialize it either, if you try to use the age variable in an instance of Person, what result will you get?  The default constructor will initialize age to 0 but if you call the second constructor, age may or may not get initialized.

The final constructor takes three arguments to initialize all three member variables.  When you create a new instance of the Person class, you can choose any of these constructors and the compiler will know which one to use based on the number of arguments you pass in as shown in this code sample.

    #include "stdafx.h"
    #include <iostream>
    #include "Person.h"
    
    using namespace std;
    
    int main()
    {
    
        // create a Person instance using default constructor
        Person *pOne = new Person();
        
        // Create a Person instance using 2 argument constructor
        Person *pTwo = new Person("Tom", "Thumb");
    
        // Create a Person instance using 3 argument constructor
        Person *pThree = new Person("Tom", "Thumb", 15);
    
    return 0;
    }
For more information , you can see:
C and C++ with Visual Studio: https://aka.ms/edx-dev210.2x-vs02

Class Destructors


Now that we know how to create objects, and we know that they consume memory while they hang around in our application's executable memory space, we also need to know how to release that memory when we no longer require the objects.  We do so with the use of a destructor.

In the previous code samples, you may have noticed that the destructor looked a lot like the default constructor, only preceded with a tilde (~).  While it looks similar to the a constructor, having no return type and the same name as the class, except for the tilde, it's important to note that a destructor cannot have any arguments passed in to it.  Therefore, when writing your own destructors, you should not place arguments between the parentheses for the destructor.

The compiler will handle the actual calling of the destructor when your object expires or the application is closing.  If you choose, you can place code inside the destructor.  One reason you may want to do this is to ensure that any resources used by the object, that may not be destroyed or cleaned up, are taken care of in your object's destructor code.

Dynamic Memory Allocation and Classes

When your application is coded, you may have no idea how many Person objects you will need during the program's lifetime.  As a result, it is likely not possible for you to create sufficient Person objects in code and let the compiler determine how much memory is required for these objects at compile time.   Chances are, you will be creating many objects dynamically as your application code executes.   In order to do so, the application must request memory from the operating system as the application is executing, (dynamically).

This topic discusses the importance of two C++ keywords new and delete.  The keyword new is used to allocate memory for an object at runtime and delete is used to release that memory.  This is also where the constructors and destructors play a big part.   You will also need to change the way you call functions and work with the objects, and we'll cover that in this topic.

Dynamically allocating memory to hold an object is done with the new keyword. Using the new keyword means that you must be making the assignment to a pointer of the correct data type.  The following code shows a valid and an invalid use of the new keyword.

    Person *pOne = new Person();

    Person per = new Person(); 

In the first line, we declare a pointer called pOne that will hold the memory address of a Person object that will reside in an area of computer memory known as the heap.  When the new keyword is encountered, the computer will set aside enough memory to hold a Person object in memory and assign that memory address to the variable pOne.   We have not created an actual object in memory yet, we have simply asked the computer to allocate sufficient memory to store the object.   How does it know how much memory is needed?  In the case of our Person class, the size is determined by looking at all the member variables, (the classes data), and based on the data types, it determines the maximum amount of memory required for the object.  No values are assigned at this time either so the compiler uses the maximum size of the specified data type for each member variable.

What happens if our class contains other classes nested within it?  The compiler will look at all the members of those classes as well and allocate sufficient memory for them as well.

In the second line of code above, we simple declare a variable to be of type Person and call it per.  However, the use of the new keyword is not legal here, at least when using Microsoft Visual Studio 2015.  The error message returned from the compiler indicates that "No suitable constructor exists to convert from Person * to Person."   This clearly indicates that new is seeking a pointer and not an object variable.

Once you have used the new keyword to dynamically create an object in memory, the way in which you access the member variables and functions is a little different than simply using the dot operator like you might be familiar with in other languages such as C# or Java.  You will now need to use the arrow selection operator to access the members of the class, as shown in the following code sample.

    Person *pOne = new Person("Gerry", "O\'Brien");
    std::cout << pOne->GetLastName() << endl;

In the first line of code, we declare a pointer *pOne and assign it a memory address using the new keyword.   The compiler sets aside memory for the object and assigns the first and last name values to the member variables using one of the constructors in our Person class.  (Refer to previous code samples for the constructors).  Because the object has been dynamically allocated with the new keyword, we must use the arrow selection operator and we see that in the second line of code where we access the GetLastName() member function to retrieve the value stored in the object pointed to by pOne.

For every object you create using the new keyword, you also need to use the delete keyword to remove the reference to the memory allocated and to release that memory back to the operating system.  Failure to do so results in a memory leak in your application.  The memory that is taken up by the object is not released back to the operating system until you call delete or until the application quits.  If you continue to allocate new objects with new and fail to use delete when finished with those objects, the memory used by your application will continue to increase.  The use of delete is rather simple as the following code snippet demonstrates.

    Person *pOne = new Person("Gerry", "O\'Brien");
    std::cout << pOne->GetLastName() << endl;

    // delete object, releasing memory
    delete pOne;

When delete is called on an object, that object's destructor is called.  The destructor is the correct location in code perform clean up operations on your object and anything that it references.  For example, you might have dynamically declared and used other objects from within your object.  In this case, you are responsible for ensuring that those other objects are also destroyed and that their memory is released.  You do this by placing the appropriate delete statements inside your object's destructor.
For more information , you can see:
Visual Studio: https://aka.ms/edx-dev210.2x-vs01
In this video you will learn Constructors briefly ..

Scope in Classes:-

What is Class Scope?

When we discuss scope in the context of classes, we are referring to the names of member variables and member functions found within the class definition.  The scope of a class within a namespace or program file is not covered in this topic.

Within a class, all of the member variables and functions are available to the class's functions.  Note that the members of a class can have access modifiers too such as private and public but that determines their visibility from outside the class.  All public and private members are available within the class to functions inside the class.

When accessing the members of a class, you use the object name followed by either a dot operator (.) or the arrow member selection operator (->) then the name of the member (variable or function).  Recall that an object is an instantiated instance of a class.  Any variables declared inside a member function are local to that function in the same way as any other function implementation in C++.

Also note that the way you call a class member will differ depending on the type of class member.  For example, for accessing static members, you do not use an instance name but rather the class name as in Math::Sum() as opposed to Math myMath; and then myMath.Sum().

Class scope permits the creation of class level functions and variables that will not conflict with functions or variables of the same name in a different class.   If we had two different class files such those shown below, the application knows which Speak() function to call based on the classes instance name.

    #include "stdafx.h"
    #include <iostream>
    #include "Person.h"
    
    01 using namespace std;
    02
    03 int main()
    04 {
    05
    06         Person person;
    07         Dog dog;
    08
    09         person.SayHello();
    10         dog.SayHello();
    11
    12         return 0;
    } 

Assume that we have two classes called Dog and Person and that the Dog's SayHello() function will output "Woof" and the Person's SayHello() function outputs "Hello".  When you call person.SayHello(), the compiler knows which SayHello function to call because it is associated with the person object which is an instance of the Person class.  Therefore, that SayHello() function will be executed.

By way of example of how to call functions using the different operators, let's consider the Person class that has been used in the Constructors topic, which is recreated here.

**Person.h**

    #pragma once
    
    #include <string>
    
    class Person
    {
    
    private:
        std::string firstName;
        std::string lastName;
    
        int age;
    
    public:
        Person();
    
        Person(std::string fName, std::string lName);
    
        Person(std::string fName, std::string lName, int age);
    
        ~Person();

        void SayHello();
    };

**Person.cpp**

    #include "stdafx.h"
    #include "Person.h"
    #include <iostream>
    
    Person::Person()
    {
    
    }
    
    Person::Person(std::string fName, std::string lName)
    {
        firstName = fName;
        lastName = lName;
    }
    
    Person::Person(std::string fName, std::string lName, int age)
    {
        firstName = fName;
        lastName = lName;
    
        age = age;
    }
    
    
    Person::~Person()
    {
    }

    void Person::SayHello
    {
        std::cout << "Hello" << std::endl;
    }

As we look at the Person.h and Person.cpp files, we notice that we have three private member variables, three public constructors, and one public method named SayHello().  To demonstrate the scope of member variables in a class we have also created the following main.cpp file.

    #include "stdafx.h"
    #include <iostream>
    #include "Person.h"
    
    01 using namespace std;
    02
    03 int main()
    04 {
    05
    06 // create a Person instance using default constructor
    07 Person *pOne = new Person();
    08
    09 // Create a Person instance using 2 argument constructor
    10 Person *pTwo = new Person("Tom", "Thumb");
    11
    12 // Create a Person instance using 3 argument constructor
    13 Person *pThree = new Person("Tom", "Thumb", 15);
    14
    15 Person p;
    16 
    17 Person &pRef = p;
    18
    19 p.SayHello();
    20
    21 // pointer method of calling a member function
    22 pOne->SayHello();
    23
    24 // reference method of calling a member function
    25 pRef.SayHello();
    26
    27 return 0;
    } 

In this code that makes use of the Person class, we see different ways of accessing the members of the Person class using instantiated objects.

On line 07, we dynamically allocate memory for a new Person object called pOne by using a pointer and the new keyword.  We do the same with two other pointers on lines 10 and 13.  The differences are that we are calling different constructors for each one.  pOne uses the default constructor, pTwo uses the 2 argument constructor while pThree uses the 3 argument constructor.  Constructors have class scope as well as they are declared within the class file.

On line 15, we create a new Person object called p without using a pointer or the new keyword.  The way that we declare our objects is important for determining how we call the member functions or access the public member variables as shown in this code sample.  On line 17 we declare a new reference variable that is a reference to the Person object we called p.  We call the SayHello() member function on p by using the dot operator on line 19 and that works.  We also call the SayHello function on line 25 using the dot operator and that works as well because we set pRef as a reference to p.

Note on line 22 however that in order to call the SayHello() function from the dynamically allocated Person object called pOne, we had to use the member selection operator (->) to gain access to the SayHello() function.
For more information , you can see:
C and C++ with Visual Studio: https://aka.ms/edx-dev210.2x-vs02
In this video you will understand  Object Lifetime in C++ (Stack/Scope Lifetimes) briefly .

Encapsulation 

class
Encapsulation 

When we consider the term encapsulation we should be clear on the context in which we are using it.  We can say that encapsulation is the programming language aspect that permits the inclusion of data and functionality into a single package.  In this definition, inclusion means to take all of the data (member variables) and functionality that acts on that data (member functions) and enclose it within the definition of a class file.

The second definition is considered data hiding or data restriction.  As an example to help explain this definition, consider the case of our Person class used in previous topics.  We may want to ensure that a user of the Person class cannot set the first name, last name, or age member variables directly.  In our sample code, we have declared these member variables to be private, which means direct access is not possible.  The only way, in the current code sample, to set these variables' values is to use the constructor.

A best practice is to also provide public functions that allow users of the class to change these values but indirectly.  That is to say, they can only modify the values through the use of a public function.  Inside that function, you, as the developer, control how data passed in from the user is handled.  For example, you might want to validate the data passed in for the age variable to ensure it is a valid age for the intended purpose.   In other words, if a user attempts to pass in a negative value or a character value for age, your public method could check for these instances and handle the situation appropriately.  You might send an error message to the user or you could trim blank spaces, etc.

The important part of encapsulation from the second definition perspective is that users of your class have no insight into how you set the values or validate the information.  It's indicative of the way in which you require absolutely no knowledge of the internal combustion engine in order to turn the ignition key and start it.

To implement encapsulation in our Person class, we could add the following code to the Person class to facilitate setting and retrieving the values for the member variables.

**Person.h**

    #pragma once

    #include <string>

    class Person
    {

    private:
        std::string firstName;
        std::string lastName;

        int age;

    public:

        int count;
        Person();

        Person(std::string fName, std::string lName);

        Person(std::string fName, std::string lName, int age);

        ~Person();

        void SetFirstName(std::string fName);
        std::string GetFirstName();
        
        void SetLastName(std::string lName);
        std::string GetLastName();

        void SetAge(int age);
        int GetAge();

        void SayHello();

};

**Person.cpp**

    #include "stdafx.h"
    #include "Person.h"
    #include <iostream>


    Person::Person()
    {
    
    }

    Person::Person(std::string fName, std::string lName)
    {
        firstName = fName;
        lastName = lName;
    }

    Person::Person(std::string fName, std::string lName, int age)
    {
        firstName = fName;
        lastName = lName;
    
        age = age;
    }


    Person::~Person()
    {
    }

    void Person::SetFirstName(std::string fName)
    {
        this->firstName = fName;
    }

    std::string Person::GetFirstName()
    {
        return this->firstName;
    }

    void Person::SetLastName(std::string lName)
    {
        this->lastName = lName;
    }

    std::string Person::GetLastName()
    {
        return this->lastName;
    }

    void Person::SetAge(int age)
    {
        if (age > 0)
        {
            this->age = age;
        }
        else
        {
            std::cout << "Please enter a valid age" << std::endl;
        }
    }

    int Person::GetAge()
    {
        return this->age;
    }

    void Person::SayHello()
    {
        std::cout << "Hello" << std::endl;
    }

**Test Program**

    int main()
    {
        Person p;

        p.SetFirstName("Gerry");
        std::cout << p.GetFirstName() << std::endl;

        // this line will output an invalid age message due to the 
        // validation check in the SetAge() function
        p.SetAge(-5);
    
        // this line will not work because firstName is private
        p.firstName = "Gerry";

        return 0;
    }


In our revised code, we have added some functions to set and get the member variables.  Outside of the constructors, this is the only way to set these values and now we actually have functions that will return these values if we need them in our program code.

In our sample test program code, we declare a Person variable called p.  We then use the dot notation to call the SetFirstName() function and also call the GetFirstName() function to output the value to the console window.  The SetFirstName() does nothing special other than to set the firstName member variable to the value passed into the function call.

Next we called the p.SetAge() function and passed in a value of -5.  This is, of course, an invalid age value.  In our SetAge() function, we have simple logic that just checks to see if the value passed in is greater than 0. If it is, the assignment is made but if not, a message is sent back to the user of the application.   The encapsulation aspect to this is simple that the user has no idea what validation code we have placed in SetAge(), nor do they know how we are checking the age, setting the age, or outputting the message.   They simply see the results of the function call.

Finally, in the last part of the code we attempt to set the firstName member variable of the p object directly.   This will generate a compiler error when you attempt to compile the program code.  Depending on your compiler, the error message may differ but Visual Studio 2015 will give the error '=': function as left operand.  In fact, the Intellisense feature in Visual Studio will not even list private member variables for auto completion of code which should be a clear indicator to the developer that the line of code contains an error.
For more information , you can see:
Visual Studio: https://aka.ms/edx-dev210.2x-vs01
In this video you will understand Encapsulation briefly .

Namespaces
Class
Example of Namespace 


Class scope covered an important aspect of working in C++ with class files but it isn't the only place that scope comes into consideration.  C++ provides the standard template library (STL) that consists of many classes and functionality.  It is conceivable that at some point in your career as a software developer, you will create classes with names that conflict with those in the STL or with other code in a software project.  C++ uses namespaces to help resolve these conflicting issues.

A namespace is a "scope container" where you can place your classes, variables, or other identifiers to prevent conflicts with others.  Anytime you want to reduce ambiguity or name collisions, you use the namespace designator ahead of the identifier.  You have already seen an example of this in the sample code used so far in this course with std::cout.  the cout function exists in the namespace std.  The :: is the scope resolution operator and allows you gain access to the cout function in the std namespace. 

A contrived example where you're code also contains a function called cout might cause naming collisions and ambiguity if your code required the use of std::cout and your cout function, unless you used namespaces.  For example, you might create a namespace for your code such as myNS.  In which case if you needed to use both cout functions in your code, you would call the C++ version using std::cout and your version using myNS::cout.   In this way, there is no ambiguity as to which function you are calling.

C++ also permits the use of using statement to help reduce the amount of code that you have to tyep when classes are inside a namespace.  For example, you could place the following statement at the top of your C++ file:

    using namespace std;

 By doing this, you can now simple use cout << "Hello"; in your code instead of typing the namespace and scope resolution operator, saving you some keystrokes.   However, take note that you cannot apply using statement if there is a chance of ambiguity in the code.  For example, you could not use the following code:

    using namespace std;
    using namespace myNS;
    
    int main()
    {
        cout << "std version of cout";
        
        cout << "myNS version of cout";
    }

The compiler has no way of knowing which cout to call in these two lines.  However you could theoretically write code such as:

    using namespace std;
    
    int main()
    {
        cout << "std version of cout";
        
        myNS::cout << "myNS version of cout";
    }

You can define your own namespace by using the keyword namespace, followed by the chosen name and then enclosing your code within the curly braces.  You also have the option of creating nested namespaces if you choose to provide more separation of identifiers in your code.  Just remember that each namespace you nest, creates more code you need to type.  A code sample demonstrates this.

    namespace Microsoft
    {
        namespace Geometry
        {
            const double PI = 3.14159;
    
            double Area(double radius)
            {
                return PI*(r*r);
            }
        }
        
    }


**Example with using statement**

    using namespace Microsoft;

    int main()
    {

        double radius = 12.5;

        double area = Geometry::Area(radius);
    }



** Example with using statement**

    int main()
    {

        double radius = 12.5;

        double area = Microsoft::Geometry::Area(radius);
    }

To keep the code simplified so we can focus on namespaces, we have omitted classes and access modifiers.   In the first code segment we have created a namespace called Microsoft and a nested namespace called Geometry.  Within Geometry we have a constant to represent PI and a function that will calcuate the area of a circle given a radius.  The second and third code segments show how we would make use of this namespace and function in code.
 In this video you will understand Namespace briefly .

Comments

Popular posts from this blog

Function and Objects

C++ Programming   Introducing to Functions Functions are a component of a programming language that permit you to break down the behavior of an application into discreet pieces of functionality, hence the name function.  A function is essentially a block of C++ code that you give a name and then call from other locations in your application, when you want the computer to perform the instructions contained in that function. You create a function by defining it.  The function definition may contain a return type, a function name, parameters to accept incoming arguments, and finally a body which contains the code that will execute as part of that function.  Functions may or may not return a value back to the caller and they may or may not accept arguments passed in to the function. When you move into more advanced C++ programming, you can also overload functions.  This refers to the practice of using the same function name to refer to multip...

Control Statements

C++  Programming  # C++ operators  Because you will start to learn about control statements in C++, it's important to understand the C++ operators that exist in the language first, as they play an important role in control statements. You will work with comparison operators to determine if values are equal, greater, or less than each other.  C++ also allows you to use mathematical operators for incrementing values to help control the number of iterations in a loop.  You can also make use of bitwise operators to speed up some operations in your code.  Operator Description + addition - subtraction * multiplication / division % modulo += (y += x) same as y = y + x -= (y -= x) same as y = y - x *= (y *= x) same as y = y * x ++ increment by 1 -- decrement by 1 == equal to != not equal to > greater than < less than >= greater than or equal to <= less than or equal to && logical AND || logical OR ! logical NOT ...