0% found this document useful (0 votes)
89 views7 pages

Scope Resolution Operator:: (C++ Only)

The :: (scope resolution) operator is used to qualify hidden names so they can still be used. It allows accessing variables or functions that have been hidden by a declaration of the same name in a local scope. Destructors are special member functions that are called automatically when an object is destroyed. They have the same name as the class but preceded by a tilde. Overloaded constructors allow constructing objects in different ways by defining multiple constructors that take different arguments. The default copy constructor initializes one object with the values of another object of the same type through a member-by-member copy.

Uploaded by

Duraiz Mumtaz
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
89 views7 pages

Scope Resolution Operator:: (C++ Only)

The :: (scope resolution) operator is used to qualify hidden names so they can still be used. It allows accessing variables or functions that have been hidden by a declaration of the same name in a local scope. Destructors are special member functions that are called automatically when an object is destroyed. They have the same name as the class but preceded by a tilde. Overloaded constructors allow constructing objects in different ways by defining multiple constructors that take different arguments. The default copy constructor initializes one object with the values of another object of the same type through a member-by-member copy.

Uploaded by

Duraiz Mumtaz
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 7

Scope resolution operator :: (C++ only)

The :: (scope resolution) operator is used to qualify hidden names so that you can still
use them. You can use the unary scope operator if a namespace scope or global
scope name is hidden by an explicit declaration of the same name in a block or class.
For example:

int count = 0;

int main(void) {
int count = 0;
::count = 1; // set global count to 1
count = 2; // set local count to 2
return 0;
}

The declaration of count declared in the main function hides the integer
named count declared in global namespace scope. The statement ::count =
1 accesses the variable named count declared in global namespace scope.
You can also use the class scope operator to qualify class names or class member
names. If a class member name is hidden, you can use it by qualifying it with its class
name and the class scope operator.
In the following example, the declaration of the variable X hides the class type X, but
you can still use the static class member count by qualifying it with the class
type X and the scope resolution operator.

#include <iostream>
using namespace std;

class X
{
public:
static int count;
};
int X::count = 10; // define static data member

int main ()
{
int X = 0; // hides class type X
cout << X::count << endl; // use static member of class
X
}
Destructors
We’ve seen that a special member function—the constructor—is called automatically
when an object is first created. You might guess that another function is called
automatically when an object is destroyed. This is indeed the case. Such a function is
called a destructor. A destructor has the same name as the constructor (which is the
same as the class name) but is preceded by a tilde:
class Foo
{
private: int data;
public: Foo() : data(0) //constructor (same name as class) { }
~Foo() //destructor (same name with tilde { }
};
Like constructors, destructors do not have a return value. They also take no arguments
(the assumption being that there’s only one way to destroy an object). The most
common use of destructors is to deallocate memory that was allocated for the object
by the constructor.

#include <iostream>
using namespace std;
class Line {
public:
void setLength( double len );
double getLength( void );
Line(); // This is the constructor declaration
~Line(); // This is the destructor: declaration

private:
double length;
};

// Member functions definitions including constructor


Line::Line(void) {
cout << "Object is being created" << endl;
}
Line::~Line(void) {
cout << "Object is being deleted" << endl;
}
void Line::setLength( double len ) {
length = len;
}
double Line::getLength( void ) {
return length;
}
// Main function for the program
int main() {
Line line;
// set line length
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}

The declaration in this definition contains some unfamiliar syntax. The function name,
setLength(), is preceded by the class name, Line, and a new symbol—the double colon
(::). This symbol is called the scope resolution operator. It is a way of specifying what
class something is associated with. In this situation, void Line::setLength( double
len ) means “the setLength( double len ) member function of the Line class.”
Figure 6.5 shows its usage.

What is the benefit to define member function


out side the class with the help of scope
resolution operator?
A function defined inside a class is taken as inline by compiler. You dont need to
specify inline keyword to make it inline, although you can but it is redundant.
What is inline function

When a function is called there is some overhead ( creation of stack , pushing values,
saving return address) in other words function calls are expensive , so when you make
a function inline it is not called instead its code is replaced at the place of call.

For small program's it really doesn't make much difference if you define member in
class or outside the class using scole resolution operator.

Why you should define functions outside the class

Lets say you have h class which has about 50 member functions. If you define every
function in the body of class that will make the code very confusing for someone who
need to understand and tweak it.

So what you do... you make two files one is interface where you declare the class and
another implementation where you give definitions for all the members.

Now if someone need to understand the functionality of your class he can use the
interface file and doesn't have to go through unnecessary code.

Normally the interface file is a header file and implementation file is source file .

Overloaded Constructors
It’s convenient to be able to give variables of type Distance a value when they are first
created. That is, we would like to use definitions like

Distance width(5, 6.25);

which defines an object, width, and simultaneously initializes it to a value of 5 for feet
and 6.25 for inches.
To do this we write a constructor like this:

Distance(int ft, float in) : feet(ft), inches(in)


{}

This sets the member data feet and inches to whatever values are passed as
arguments to the constructor. So far so good. However, we also want to define
variables of type Distance without initializing them, as we did in ENGLOBJ.

Distance dist1, dist2;


In that program there was no constructor, but our definitions worked just fine. How
could they work without a constructor? Because an implicit no-argument constructor is
built into the program automatically by the compiler, and it’s this constructor that
created the objects, even though we didn’t define it in the class. This no-argument
constructor is called the default constructor. If it weren’t created automatically by the
constructor, you wouldn’t be able to create objects of a class for which no constructor
was defined. Often we want to initialize data members in the default (no-argument)
constructor as well. If we let the default constructor do it, we don’t really know what
values the data members may be given. If we care what values they may be given, we
need to explicitly define the constructor. In ENGLECON we show how this looks:

Distance() : feet(0), inches(0.0) //default constructor


{ } //no function body, doesn’t do anything

The data members are initialized to constant values, in this case the integer value 0
and the float value 0.0, for feet and inches respectively. Now we can use objects
initialized with the no-argument constructor and be confident that they represent no
distance (0 feet plus 0.0 inches) rather than some arbitrary value.
Since there are now two explicit constructors with the same name, Distance(), we say
the constructor is overloaded. Which of the two constructors is executed when an
object is created depends on how many arguments are used in the definition:

Distance length; // calls first constructor


Distance width(11, 6.0); // calls second constructor

The Default Copy Constructor


We’ve seen two ways to initialize objects. A no-argument constructor can initialize data
members to constant values, and a multi-argument constructor can initialize data
members to values passed as arguments. Let’s mention another way to initialize an
object: you can initialize it with another object of the same type. Surprisingly, you don’t
need to create a special constructor for this; one is already built into all classes. It’s
called the default copy constructor. It’s a one argument constructor whose argument is
an object of the same class as the constructor. The ECOPYCON program shows how
this constructor is used.

// ecopycon.cpp
// initialize objects using default copy constructor
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class Distance //English Distance class
{
private:
int feet;
float inches;
public:
//constructor (no args)
Distance() : feet(0), inches(0.0)
{}
//Note: no one-arg constructor
//constructor (two args)
Distance(int ft, float in) : feet(ft), inches(in)
{}
void getdist() //get length from user
{
cout << “\nEnter feet: “; cin >> feet;
cout << “Enter inches: “; cin >> inches;
}
void showdist() //display distance
{ cout << feet << “\’-” << inches << ‘\”’; }
};
////////////////////////////////////////////////////////////////
int main()
{
Distance dist1(11, 6.25); //two-arg constructor
Distance dist2(dist1); //one-arg constructor
Distance dist3 = dist1; //also one-arg constructor
//display all lengths
cout << “\ndist1 = “; dist1.showdist();
cout << “\ndist2 = “; dist2.showdist();
cout << “\ndist3 = “; dist3.showdist();
cout << endl;
return 0;
}

We initialize dist1 to the value of 11’-6.25” using the two-argument constructor. Then
we define two more objects of type Distance, dist2 and dist3, initializing both to the
value of dist1. You might think this would require us to define a one-argument
constructor, but initializing an object with another object of the same type is a special
case. These definitions both use the default copy constructor. The object dist2 is
initialized in the statement Distance dist2(dist1);
This causes the default copy constructor for the Distance class to perform a member-
by-member copy of dist1 into dist2. Surprisingly, a different format has exactly the
same effect, causing dist1 to be copied member-by-member into dist3:
Distance dist3 = dist1;

Although this looks like an assignment statement, it is not. Both formats invoke the
default copy constructor, and can be used interchangeably. Here’s the output from the
program:
dist1 = 11’-6.25”
dist2 = 11’-6.25”
dist3 = 11’-6.25”

This shows that the dist2 and dist3 objects have been initialized to the same value as
dist1.

You might also like