copy constructor, constructor, friend, basic idea on C++
Any data which is declared private inside a class is not accessible from outside the class. A function which is not a member or an external class can never access such private data. But there may be some cases, where a programmer will need need access to the private data from non-member functions and external classes. C++ offers some exceptions in such cases.
A class can allow non-member functions and other classes to access its own private data, by making them as friends. This part of C++ tutorial essentially gives two important points.
- Once a non-member function is declared as a friend, it can access the private data of the class
- similarly when a class is declared as a friend, the friend class can have access to the private data of the class which made this a friend
Let's see a sample in this C++ tutorial for each of the above cases.
C++ Tutorial - Friend function sample:
#include <iostream.h>
//Declaration of the function to be made as friend for the C++ Tutorial sample
int AddToFriend(int x);
class CPP_Tutorial
{
int private_data;
friend int AddToFriend(int x);
public:
CPP_Tutorial()
{
private_data = 5;
}
};
int AddToFriend(int x)
{
CPP_Tutorial var1;
return var1.private_data + x;
}
int main()
{
cout << "Added Result for this C++ tutorial: "<< AddToFriend(4)<<endl;
}
The output of the above C++ Tutorial sample will be
Added Result for this C++ tutorial: 9
C++ tutorial - friend class:
Declaration of a friend class is also similar. Only thing is a class definition is slightly different.
C++ Tutorial - Friend function:
#include < iostream.h >
class CPP_Tutorial
{
int private_data;
friend class friendclass;
public:
CPP_Tutorial()
{
private_data = 5;
}
};
class friendclass
{
public:
int subtractfrom(int x)
{
CPP_Tutorial var2;
return var2.private_data - x;
}
};
int main()
{
friendclass var3;
cout << "Added Result for this C++ tutorial: "<< var3.subtractfrom(2)<<ENDL;
}
The output of the above C++ Tutorial sample will be
Subtracted Result for this C++ tutorial: 3
This is a good way out given by C++ to avoid restrictions on private variables. But this should be used with caution though. If all the functions and classes are declared as friends, then the concept of encapsulation and data security will go for a toss.
That is why the concept of friend functions and classes should be used with proper judgment.
Operator overloading is a beautiful concept in C++. At times it is little confusing also. But actually they are quite easy. Anyway, here is an example for overloading the stream operators.
The best way to overload the stream operators is not to make them members of any class, but to keep them as friends. i.e., wherever there is a need to use the stream operators, use them as friend functions with the suitable parameters.
The following example shows the use of these operators for a class.
#include <iostream.h>
#include <string.h>
class Base
{
char strVal[100];
public:
Base(){ strcpy(strVal,"");}
Base(char *val){ strcpy(strVal,val);}
~Base(){*strVal = '\0';}
friend istream& operator >>(istream &is,Base &obj);
friend ostream& operator <<(ostream &os,const Base &obj);
};
istream& operator >>(istream &is,Base &obj)
{
is>>strVal;
return is;
}
ostream& operator <<(ostream &os,const Base &obj)
{
os<<obj.strVal;
return os;
}
void main()
{
Base b;
cin>>b;
cout<<"Printing the value\n";
cout<<b<<endl;
}
If there are derived classes which need to use the stream operators, one way is to define some more versions of the stream operators with the derived class Parameters.
Copy constructor is
- a constructor function with the same name as the class
- used to make deep copy of objects.
There are 3 important places where a copy constructor is called.
- When an object is created from another object of the same type
- When an object is passed by value as a parameter to a function
- When an object is returned from a function
If a copy constructor is not defined in a class, the compiler itself defines one. This will ensure a shallow copy. If the class does not have pointer variables with dynamically allocated memory, then one need not worry about defining a copy constructor. It can be left to the compiler's discretion.
But if the class has pointer variables and has some dynamic memory allocations, then it is a must to have a copy constructor.
For ex:
class A //Without copy constructor
{
private:
int x;
public:
A() {A = 10;}
~A() {}
}
class B //With copy constructor
{
private:
char *name;
public:
B()
{
name = new char[20];
}
~B()
{
delete name[];
}
//Copy constructor
B(const B &b)
{
name = new char[20];
strcpy(name, b.name);
}
};
Let us Imagine if you don't have a copy constructor for the class B. At the first place, if an object is created from some existing object, we cannot be sure that the memory is allocated. Also, if the memory is deleted in destructor, the delete operator might be called twice for the same memory location.
This is a major risk. One happy thing is, if the class is not so complex this will come to the fore during development itself. But if the class is very complicated, then these kind of errors will be difficult to track.
In Windows this will lead to an application popup and unix will issue a core dump. A careful handling of this will avoid a lot of nuisance.
A class in C++ is an encapsulation of data members and functions that manipulate the data. The class can also have some other important members which are architecturally important.
This C++ Tutorial discusses the components of a C++ class. More C++ tutorials will follow.
C++ Tutorial - Class Data Members:
Very important point about the Data members in this C++ Tutorial! This title is not a keyword or a data type in C++. This is just to explain one of the logical classifications of the types of members that are available in C++.
The data members can be of any legal data type, a class type, a struct type etc., They can also be declared as pointers and accessible normally as like other data members. The Example class given below in this C++ tutorial has two data members x and y of type integer.
C++ Tutorial - Function members in classes:
Functions declared inside a class can be any of the following four types. This C++ Tutorial explains each one of them as below.
Ordinary member functions :
These are ordinary functions defined with a return type and parameters. The return type can also be void. The special trait about member functions is they can access the private/protected data members of their class and manipulate them. No external functions can access the private/protected data members of a class. The sample below this C++ Tutorial uses an ordinary member function Add(), returning an integer value.
Constructors:
Constructors in C++ are special member functions of a class. They have the same name as the Class Name. There can be any number of overloaded constructors inside a class, provided they have a different set of parameters. There are some important qualities for a constructor to be noted.
- Constructors have the same name as the class.
- Constructors do not return any values
- Constructors are invoked first when a class is initialized. Any initializations for the class members, memory allocations are done at the constructor.
In the example class given below in this C++ tutorial has the constructor Example_Class(), with the same name as the class.
Destructors:
Destructors in C++ also have the same name, except for the fact that they are preceded by a '~' operator. The destructors are called when the object of a class goes out of scope. It is not necessary to declare a constructor or a destructor inside a class. If not declared, the compiler will automatically create a default one for each. If the constructor/destructor is declared as private, then the class cannot be instantiated. Check below for the sample class of the C++ tutorial for an example of destructor.
C++ Tutorial - Access Level:
The classes in C++ have 3 important access levels. They are Private, Public and Protected. The explanations are as follows.
Private:
The members are accessible only by the member functions or friend functions.
Protected:
These members are accessible by the member functions of the class and the classes which are derived from this class.
Public:
Accessible by any external member. Look at the sample class below.
C++ Tutorial - Example of a class:
class Example_class //Sample Class for the C++ Tutorial
{
private:
int x; //Data member
int y; // Data member
public:
Example_Class() //Constructor for the C++ tutorial
{
x = 0;
y = 0;
}
~Example_Class() //destructor for the C++ Tutorial
{ }
int Add()
{
return x+y;
}
};