•
•
•
•
What is DaniWeb IT Discussion Community?
You're currently browsing the C++ section within the Software Development category of DaniWeb, a massive community of 401,439 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 2,873 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our C++ advertiser: Programming Forums
Views: 11053 | Replies: 7
![]() |
•
•
Join Date: Sep 2003
Location: deep withing 100100010100
Posts: 200
Reputation:
Rep Power: 5
Solved Threads: 2
•
•
Join Date: Feb 2002
Location: Lawn Guylen, NY
Posts: 10,885
Reputation:
Rep Power: 32
Solved Threads: 110
Sure. Is it like via another object of the same class?
Dani the Computer Science Gal
Do you run a computer-related website? Feature it in our niche link directory!
Do you run a computer-related website? Feature it in our niche link directory!
•
•
Join Date: Sep 2003
Location: deep withing 100100010100
Posts: 200
Reputation:
Rep Power: 5
Solved Threads: 2
How to access the Private data members of a class in C++
(from a non-friend function)
All the information listed below is in context of Turbo C++ 3.0. It may or may not work with later versions.
In C++, when we declare a class with public and private members; by default, we cannot access the private data members from outside the class, unless we declare the other function as friend of the class. But there is a work-around, using which we may access the private data members from outside the class without the use of a friend.
Suppose we have a class named demo, which is given as: -
class demo{
private:
int number;
char name[6];
float pi;
public:
demo( ){
number=226;
strcpy(name,"Môhit");
pi=3.1476;
}
};
It contains three private data members, storing an integer, a string of 5+1 characters, and a float type quantity, respectively. It also has a constructor, which initialises the value of the data members.
Now we may declare a demo type object named objDemo :-
Demo objDemo;
When any class type object is declared the data members occupy the space starting from the initial address of the object and they do so in the order in which they are declared within a class.
So this object objDemo will be created and a memory space will be allocated to it in the RAM. And all of its data members will be present in that memory space of objDemo, starting from &objDemo.
With this funda we now know that the integer will be allocated the starting address of object itself, followed by the string and float. Now in order to access these members we’ll store the address of object in a void type pointer, b’coz it has to be type-casted later.
void *prtDemo=&objDemo;
Now we can access the first data member (i.e. int number) by typecasting it into ‘int*’ but in order to access all the members in a simpler way we’ll create a structure with same type of data members as in objDemo and too in the same order.
struct cpyData{
int number;
char name[6];
float pi;
};
Then we will create a pointer to the structure of type cpyData and store in it the address of objDemo i.e. type-cast the void cpyDemo to ‘*cpyData’ :-
cpyData *ptrData = (cpyData*)ptrDemo;
Now we have a pointer which points to the private data members of the object objDemo. To access them we can use this pointer with an indirection operator (->).
cout<<ptrData->number<<endl;
cout<<ptrData->name<<endl;
cout<<ptrData->pi<<endl;
This code will display the private data members of objDemo from the function, which contains the declarations, and assignments of pointers. J
To change the content of the private data members you may manipulate the same code. E.g. :
ptrData->number=1645;
strcpy(ptrData->name,”Manù”);
This code will not work for the static members present in class b’coz they are not present within the memory space of the object but at another location in RAM, which starts at 0x00AA. U may use this address to access the first static data member and operate on this address to access the other static data members.
code :-
_______
#include <iostream.h>
#include <conio.h>
#include <string.h>
/* Declaring a class named demo */
class demo{
private:
int number;
char name[6];
float pi;
public:
demo( ){ /* constructor */
number=226;
strcpy(name,"Môhit");
pi=3.1476;
}
};
/* Declaring a structure with data members same as class demo */
struct cpyData{
int number;
char name[6];
float pi;
};
void main( ){
clrscr( ); /* clear screen */
demo objDemo; /* declaring a demo type object */
void *ptrDemo = &objDemo; /* Getting the address of objDemo */
cpyData *ptrData = (cpyData*)ptrDemo; /* type-casting the address of objDemo to *cpyData */
cout<<ptrData->number<<endl; /* Displaying the private data members */
cout<<ptrData->name<<endl;
cout<<ptrData->pi<<endl;
ptrData->number=1645; /* Changing the contents of a private data member */
strcpy(ptrData->name,"Manù");
cout<<ptrData->number<<endl; /* Displaying the changed data member */
cout<<ptrData->name;
}
Credits:Mohit
(from a non-friend function)
All the information listed below is in context of Turbo C++ 3.0. It may or may not work with later versions.
In C++, when we declare a class with public and private members; by default, we cannot access the private data members from outside the class, unless we declare the other function as friend of the class. But there is a work-around, using which we may access the private data members from outside the class without the use of a friend.
Suppose we have a class named demo, which is given as: -
class demo{
private:
int number;
char name[6];
float pi;
public:
demo( ){
number=226;
strcpy(name,"Môhit");
pi=3.1476;
}
};
It contains three private data members, storing an integer, a string of 5+1 characters, and a float type quantity, respectively. It also has a constructor, which initialises the value of the data members.
Now we may declare a demo type object named objDemo :-
Demo objDemo;
When any class type object is declared the data members occupy the space starting from the initial address of the object and they do so in the order in which they are declared within a class.
So this object objDemo will be created and a memory space will be allocated to it in the RAM. And all of its data members will be present in that memory space of objDemo, starting from &objDemo.
With this funda we now know that the integer will be allocated the starting address of object itself, followed by the string and float. Now in order to access these members we’ll store the address of object in a void type pointer, b’coz it has to be type-casted later.
void *prtDemo=&objDemo;
Now we can access the first data member (i.e. int number) by typecasting it into ‘int*’ but in order to access all the members in a simpler way we’ll create a structure with same type of data members as in objDemo and too in the same order.
struct cpyData{
int number;
char name[6];
float pi;
};
Then we will create a pointer to the structure of type cpyData and store in it the address of objDemo i.e. type-cast the void cpyDemo to ‘*cpyData’ :-
cpyData *ptrData = (cpyData*)ptrDemo;
Now we have a pointer which points to the private data members of the object objDemo. To access them we can use this pointer with an indirection operator (->).
cout<<ptrData->number<<endl;
cout<<ptrData->name<<endl;
cout<<ptrData->pi<<endl;
This code will display the private data members of objDemo from the function, which contains the declarations, and assignments of pointers. J
To change the content of the private data members you may manipulate the same code. E.g. :
ptrData->number=1645;
strcpy(ptrData->name,”Manù”);
This code will not work for the static members present in class b’coz they are not present within the memory space of the object but at another location in RAM, which starts at 0x00AA. U may use this address to access the first static data member and operate on this address to access the other static data members.
code :-
_______
#include <iostream.h>
#include <conio.h>
#include <string.h>
/* Declaring a class named demo */
class demo{
private:
int number;
char name[6];
float pi;
public:
demo( ){ /* constructor */
number=226;
strcpy(name,"Môhit");
pi=3.1476;
}
};
/* Declaring a structure with data members same as class demo */
struct cpyData{
int number;
char name[6];
float pi;
};
void main( ){
clrscr( ); /* clear screen */
demo objDemo; /* declaring a demo type object */
void *ptrDemo = &objDemo; /* Getting the address of objDemo */
cpyData *ptrData = (cpyData*)ptrDemo; /* type-casting the address of objDemo to *cpyData */
cout<<ptrData->number<<endl; /* Displaying the private data members */
cout<<ptrData->name<<endl;
cout<<ptrData->pi<<endl;
ptrData->number=1645; /* Changing the contents of a private data member */
strcpy(ptrData->name,"Manù");
cout<<ptrData->number<<endl; /* Displaying the changed data member */
cout<<ptrData->name;
}
Credits:Mohit
Forum bully
•
•
Join Date: Sep 2003
Location: San Diego, CA, USA
Posts: 75
Reputation:
Rep Power: 5
Solved Threads: 0
•
•
Join Date: May 2004
Location: Egypt - Cairo
Posts: 129
Reputation:
Rep Power: 5
Solved Threads: 2
C++ : One-Hour Overview
(1) User-Defined ADT (Abstract Data Types)
e.g.: "enum" creates a user-defined type.
enum Months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
Months x,y;
x = FEB; y = DEC;
"struct" creates more flexible user-defined types.
How to define a structure in C and C++.
struct Date {
int mm;
int dd;
int yy;
};
mm, dd and yy are member variables of Date.
struct Complex {
float real;
float imag;
};
struct Person {
long int ssn;
char name[40];
int age;
Date dob;
float salary;
};
A user-defined type can have non-uniform member variables.
How to use a user-defined structure.
Date x, y, *z; // declaring variables x and y of type Date, and a pointer z to Date type variable.
x.mm = 1;
x.dd = 18;
x.yy = 1998;
// x.mm x.dd x.yy 1 18 1998
y = x;
cout << y.mm << '/' << y.dd << '/' << y.yy << endl;
z = &x;
cout << z->mm << '/' << z->dd << '/' << z->yy << endl;
Person jeo;
jeo.ssn = 123456789;
strcpy(jeo.name,"Jeo Gates");
jeo.age = 20;
jeo.dob.mm = 7;
jeo.dob.dd = 25;
jeo.dob.yy = 1978;
jeo.salary = 100000.0;
(2) Simple Classes
C++ : Classes and Objects.
A class in C++ is a user-defined ADT, just like a struct in C.
An object in C++ is just like a variable in C.
Example:
C (defining a structure and declaring a variable):
struct XY {
int x;
int y;
} ;
void main ()
{
XY v;
v.x = 0; v.y = 0;
cout << v.x << v.y;
}
C++: (defining a class and declaring a variable)
class XY {
public:
int x;
int y;
};
void main ()
{
XY v;
v.x = 0; v.y = 0;
cout << v.x << v.y;
}
Like structures, classes only define how objects should look like and do not use any memory. Like variables, objects are declared by the programmer and they use memories.
(3) Member Functions
class XY {
public:
int x; int y;
void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
void main ()
{
XY v;
v.x = 0; v.y = 0;
v.print();
}
(4) Constructors and Destructors
A constructor is special member function of a class that has the same name as the class.
class XY {
public:
int x; int y;
XY( ) {x = 0; y = 0;}
void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
void main ()
{
XY v; // constructor is automatically called here.
v.print(); // no need of v.x = 0; v.y = 0;
}
We can code class definition in xy.h and the main function in main.cpp;
Classes are easy to use and to modify (e.g. adding z).
Note:
(1) A constructor has the same name as the class.
(2) There is no return type or return value.
(3) The compiler provides a default constructor:
XY( ) { } // do-nothing
It is better to always provide your own one.
(4) A class can have multiple constructors.
Destructor is another special member function that has the same name as the class preceded with a ~.
(1) Its name consists of the class name preceded by a tilde (~): ~XY ( ) { }
(2) It has no arguments and returns nothing.
(3) The compiler provides a default destructor:
~XY( ) { } // do-nothing
Provide your own destructor if you allocate memories in the object.
(4) A class can have only one constructor.
(5) Overloaded Functions
Overloaded functions: multiple functions have the same name. The compiler decides which one to invoke depending on number of arguments and the types of the arguments.
class XY {
public:
int x; int y;
XY( ) {x = 0; y = 0;}
XY(int xin, int yin) {x = xin; y = yin;}
void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
XY u; // XY( ) {x = 0; y = 0;} called
XY v(1,1), w(2,2) ; // XY(int xin, int yin) {x = xin; y = yin;} called
(6) Encapsulation
class XY {
private:
int x; int y;
public:
XY( ) {x = 0; y = 0;}
void set(int xin, int yin) { x = xin; y = yin; }
void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
XY v;
v.x = 1; v.y = 1; // not allowed, x&y are private.
v.set(1,1); // ok, set( ) is a public function.
Encapsulation: Private members of a class can only be accessed by its member functions or friend functions.
A class can provide public functions for others to access its private members.
A helper function is a private member function that is only accessible by other member functions.
"protected" members are private but can be accessed by the derived (child) classes.
(7) Inheritance
Orbiters: Planets and Spaceships.
Class Orbiter {
protected:
int dMass;
XY xyPosition;
public:
Orbiter(XY Position, int Mass){ xy Position = Position; dMass = Mass;}
XY GetPosition( ) const { return xyPosition; }
void Fly( ) { xyPosition.x += 10; xyPosition.y += 10;}
virtual void Display( ) const
{ cout << "The orbiter is at " << "("<< x << "," << y << ")." << endl; }
};
Note:
(1) A "const" function can't modify any data members;
(2) A virtual function can be overridden by the derived classes.
(3) A pure virtual ( = 0) function has to be overridden by the derived classes.
virtual void Display( ) const = 0;
(4) XY xyPosition declares an imbedded object.
Derived (Child) Classes: inherit all the data members and member functions (except constructors and destructors) of their base (parent) class.
class Planet : public Orbiter {
public:
Planet(XY xyPosition, int dMass) : Orbiter(xyPosition, dMass) { /* a do nothing function */ }
virtual void Display( ) const
{cout << "The planet is at " << "("<< x << "," << y << ")." << endl; }
};
Planet Earth(ePos,eMass), Jupiter(jPos,jMass);
Note:
(1) Child "class" inherits from parent "class". The parent (base) class has to be defined first. Similar to structure in structure in C.
(2) Each "child" object is an instance of the child class. It has all the member data and functions of both the child class and the parent class.
The Earth or Jupiter Object
dMass
xyPosition
xyThrust
Planet( )
Fly( )
GetPosition( )
Display( )
(3) A "child" object is independent from the object instances of the parent class. Object Earth does not need an Obiter object to exist. It does need the Obiter class to be defined. Inheritance is from a class not from an object.
(4) Orbiter constructor is called first before executing the Planet constructor.
Planet (…) : Orbiter (…) { … }
(5) The default constructor of a child class automatically calls the constructor of the parent class before executing the code in the default constructor. The default destructor does the opposite sequence.
(6)":" inheritance operator, which parent.
"::" scope resolution operator, which class.
Children can be different.
class Spaceship : public Orbiter {
private:
int dFuel;
public:
Spaceship (XY xyPosition, int dMass, int Fuel) :
Orbiter(xyPosition, dMass) { dFuel = Fuel; }
void Display( ) const
{cout << "The spaceship is at " << "("<< x << "," << y << ")." << endl; }
void FireThrusters() { x += 10; y += 10; Fuel -= 1; }
};
(8) Copy Constrctor, Assignment and Other Operators
Copy constructor:
XY(const XY& c) {
x = c.x;
y = c.y;
}
XY a(1,2);
XY b(a);
? b = a;
Assignment Operators:
const XY& operator= (const XY& e) {
x = e.x;
y = e.y;
return *this;
}
Note:
(1) function name => operator=
b.operator=(b);
(2) argument => operand
(3) "this" is a pointer generated by the compiler which always points to the current (this) object.
(4) order : object operator operand
(5) returned reference is for chaining.
XY a(1,1);
c = b = a;
? XY c = a + b;
a + b ==> a.operator+(b)
XY XY::operator + (const XY& xy) {
XY z (x + xy.x, y + xy.y);
return z;
}
XY XY::operator + (const XY& xy) { return XY(x + xy.x, y + xy.y);}
? XY c = a - b;
XY XY::operator - (const XY& xy) { return XY(x - xy.x, y - xy.y);}
? XY c = a-;
XY XY::operator - ( ) { return XY(x-, y-);}
? XY c = a * 3;
XY XY::operator * (const int dMult) { return XY(x * dMult, y * dMult);}
? a *= 3;
const XY& XY::operator* = (const int dMult) { x *= dMult; y *= dMult; return *this;}
Note: a is modified.
? XY c = 3 * a;
Global Operator: not belonging to any class.
XY operator * (const int dMult, const XY& xy) { return XY(dMult * xy.x, dMult * xy.y);}
Note:
(1) Order change : operand operator operand .
(2) Related member variables need to be public or make the global operator friend.
(9) Stack and Heap Objects
Stack objects: local objects that are not static.
Heap objects: objects allocated on the heap so that their memory remains until being specifically freed.
New & delete: (similar to malloc & free in C)
XY* pxy;
pxy = new XY(1,1);
pxy->display();
delete pxy;
pxy = new XY[64]; // cannot specify initializer for arrays
pxy[0].display();
delete [] pxy;
Note:
(1) Array deletion needs [], different from free.
(2) delete has to go with new, free has to go with malloc.
(10) Friend Classes and Friend Functions
A friend is nonmember of a class that is given access to the nonpublic members of a class.
Friend Classes
class YX {
friend class XY;
private:
int y; int x;
public:
YX() {y = x = 0; }
};
class XY {
public:
int x; int y;
void copyYX(const YX& yx) { x = yx.x; y = yx.y; }
void writeYX(YX& yx) { yx.x = x; yx.y = y; }
};
XY xy; YX yx;
xy.copyYX(yx);
Note:
(1) All member functions of XY are allowed to access any data of YX,
because YX has declared XY as a friend.
(2) Friendship can be declared to individual functions.
Friend Functions:
class YX {
friend void XY::copyYX(const YX& yx);
friend void XY::writeYX(YX& yx);
friend int tan(const YX& yx); // global
…
};
int tan(const YX& yx) { return yx.x / yx.y; }
(11) Polymorphism
Polymorphism is the ability to call a variety of functions using exactly the same interface.
Obiter o(1,1); Planet p(2,2); Spaceship s(3,3);
Obiter *a[3];
a[0] = (Obiter *) &o;
a[1] = (Obiter *) &p;
a[2] = (Obiter *) &s;
for(i=0; i<=2; i++) a[i]->Display();
/* => o.Display(); p.Display(); s.Display(); */
The orbitor is at (1,1).
The planet is at (2,2).
The spaceship is at (3,3).
Comparison of polymorphic and overloaded functions:
(1) A set of polymorphic functions have exactly the same name, same number of parameters of the same types. A set of overloaded functions have the same name but with different number or different type of parameters.
(2) A set of polymorphic functions belong to different classes of a class hierarchy. The function in the base class has to be virtual. A set of overloaded functions belong to the same class.
(3) Polymorphic functions are differentiated by the (creation) classes of the objects. Overloaded functions are differentiated by their arguments (number and type).
(12) Templets: Parameterized class definition.
Regular class definition: class Name { ... };
Regular object declaration: Name obj;
Templet definition: template <class Type>
class Name {Type ... }
Templet object declaration: Name<Type> obj;
Example: any-type array class:
template <class Type>
class Array {
public:
Type *ap;
int size;
Array(int sz) {size = sz; ap = new Type [size]; }
~Array() {delete [] ap;}
Type& operator[] (int index) { return ap[index]; }
};
Array<int> ia(4);
Array<char> ca(5);
Array<double> da(6);
e.g. Type is int.
Array<int> ia(4);
class Array {
public:
int *ap;
int size;
Array(int sz) {size = sz; ap = new int [size]; }
~Array() {delete [] ap;}
int& operator[] (int index) { return ap[index]; }
};
(13) Static Class Members
Static data members are global to the whole class rather than local to any specific object.
class XY {
public:
static int s_nCount;
int nCount;
XY() : nCount(0) { s_nCount++; nCount++;}
void Display() { cout << s_nCount << "," << nCount << endl; }
static int& GetCounter() { return s_nCount; }
};
int XY::s_nCount = 0;
void main()
{
XY u; // u.s_nCount == 1 and u.nCount == 1
XY v; // v.s_nCount == 2 and v.nCount == 1
XY w; // w.s_nCount == 3 and w.nCount == 1
u.Display(); // 3,1
v.Display(); // 3,1
w.Display(); // 3,1
}
Static Member Functions are for accessing static member data.
void main()
{
XY::GetCounter()++;
XY u, v, w;
XY::GetCounter()++;
u.s_nCount++;
v.s_nCount++;
w.s_nCount++;
u.Display(); // 8,1
}
Note:
(1) A static function can be used without declaring an object.
(2) It does not contain a "this" pointer.
(3) It cannot reference any non-static member (data or function).
(4) Non-static functions can access static members.
(14) Separating Class Definitions from Code
XY.h contains XY class definition.
XY.cpp contains XY member functions.
Class users need only check on XY.h for information.
Class authors write the functions in .cpp
(1) User-Defined ADT (Abstract Data Types)
e.g.: "enum" creates a user-defined type.
enum Months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
Months x,y;
x = FEB; y = DEC;
"struct" creates more flexible user-defined types.
How to define a structure in C and C++.
struct Date {
int mm;
int dd;
int yy;
};
mm, dd and yy are member variables of Date.
struct Complex {
float real;
float imag;
};
struct Person {
long int ssn;
char name[40];
int age;
Date dob;
float salary;
};
A user-defined type can have non-uniform member variables.
How to use a user-defined structure.
Date x, y, *z; // declaring variables x and y of type Date, and a pointer z to Date type variable.
x.mm = 1;
x.dd = 18;
x.yy = 1998;
// x.mm x.dd x.yy 1 18 1998
y = x;
cout << y.mm << '/' << y.dd << '/' << y.yy << endl;
z = &x;
cout << z->mm << '/' << z->dd << '/' << z->yy << endl;
Person jeo;
jeo.ssn = 123456789;
strcpy(jeo.name,"Jeo Gates");
jeo.age = 20;
jeo.dob.mm = 7;
jeo.dob.dd = 25;
jeo.dob.yy = 1978;
jeo.salary = 100000.0;
(2) Simple Classes
C++ : Classes and Objects.
A class in C++ is a user-defined ADT, just like a struct in C.
An object in C++ is just like a variable in C.
Example:
C (defining a structure and declaring a variable):
struct XY {
int x;
int y;
} ;
void main ()
{
XY v;
v.x = 0; v.y = 0;
cout << v.x << v.y;
}
C++: (defining a class and declaring a variable)
class XY {
public:
int x;
int y;
};
void main ()
{
XY v;
v.x = 0; v.y = 0;
cout << v.x << v.y;
}
Like structures, classes only define how objects should look like and do not use any memory. Like variables, objects are declared by the programmer and they use memories.
(3) Member Functions
class XY {
public:
int x; int y;
void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
void main ()
{
XY v;
v.x = 0; v.y = 0;
v.print();
}
(4) Constructors and Destructors
A constructor is special member function of a class that has the same name as the class.
class XY {
public:
int x; int y;
XY( ) {x = 0; y = 0;}
void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
void main ()
{
XY v; // constructor is automatically called here.
v.print(); // no need of v.x = 0; v.y = 0;
}
We can code class definition in xy.h and the main function in main.cpp;
Classes are easy to use and to modify (e.g. adding z).
Note:
(1) A constructor has the same name as the class.
(2) There is no return type or return value.
(3) The compiler provides a default constructor:
XY( ) { } // do-nothing
It is better to always provide your own one.
(4) A class can have multiple constructors.
Destructor is another special member function that has the same name as the class preceded with a ~.
(1) Its name consists of the class name preceded by a tilde (~): ~XY ( ) { }
(2) It has no arguments and returns nothing.
(3) The compiler provides a default destructor:
~XY( ) { } // do-nothing
Provide your own destructor if you allocate memories in the object.
(4) A class can have only one constructor.
(5) Overloaded Functions
Overloaded functions: multiple functions have the same name. The compiler decides which one to invoke depending on number of arguments and the types of the arguments.
class XY {
public:
int x; int y;
XY( ) {x = 0; y = 0;}
XY(int xin, int yin) {x = xin; y = yin;}
void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
XY u; // XY( ) {x = 0; y = 0;} called
XY v(1,1), w(2,2) ; // XY(int xin, int yin) {x = xin; y = yin;} called
(6) Encapsulation
class XY {
private:
int x; int y;
public:
XY( ) {x = 0; y = 0;}
void set(int xin, int yin) { x = xin; y = yin; }
void print( ) { cout << "x = " << x << "y = " << y << endl; }
};
XY v;
v.x = 1; v.y = 1; // not allowed, x&y are private.
v.set(1,1); // ok, set( ) is a public function.
Encapsulation: Private members of a class can only be accessed by its member functions or friend functions.
A class can provide public functions for others to access its private members.
A helper function is a private member function that is only accessible by other member functions.
"protected" members are private but can be accessed by the derived (child) classes.
(7) Inheritance
Orbiters: Planets and Spaceships.
Class Orbiter {
protected:
int dMass;
XY xyPosition;
public:
Orbiter(XY Position, int Mass){ xy Position = Position; dMass = Mass;}
XY GetPosition( ) const { return xyPosition; }
void Fly( ) { xyPosition.x += 10; xyPosition.y += 10;}
virtual void Display( ) const
{ cout << "The orbiter is at " << "("<< x << "," << y << ")." << endl; }
};
Note:
(1) A "const" function can't modify any data members;
(2) A virtual function can be overridden by the derived classes.
(3) A pure virtual ( = 0) function has to be overridden by the derived classes.
virtual void Display( ) const = 0;
(4) XY xyPosition declares an imbedded object.
Derived (Child) Classes: inherit all the data members and member functions (except constructors and destructors) of their base (parent) class.
class Planet : public Orbiter {
public:
Planet(XY xyPosition, int dMass) : Orbiter(xyPosition, dMass) { /* a do nothing function */ }
virtual void Display( ) const
{cout << "The planet is at " << "("<< x << "," << y << ")." << endl; }
};
Planet Earth(ePos,eMass), Jupiter(jPos,jMass);
Note:
(1) Child "class" inherits from parent "class". The parent (base) class has to be defined first. Similar to structure in structure in C.
(2) Each "child" object is an instance of the child class. It has all the member data and functions of both the child class and the parent class.
The Earth or Jupiter Object
dMass
xyPosition
xyThrust
Planet( )
Fly( )
GetPosition( )
Display( )
(3) A "child" object is independent from the object instances of the parent class. Object Earth does not need an Obiter object to exist. It does need the Obiter class to be defined. Inheritance is from a class not from an object.
(4) Orbiter constructor is called first before executing the Planet constructor.
Planet (…) : Orbiter (…) { … }
(5) The default constructor of a child class automatically calls the constructor of the parent class before executing the code in the default constructor. The default destructor does the opposite sequence.
(6)":" inheritance operator, which parent.
"::" scope resolution operator, which class.
Children can be different.
class Spaceship : public Orbiter {
private:
int dFuel;
public:
Spaceship (XY xyPosition, int dMass, int Fuel) :
Orbiter(xyPosition, dMass) { dFuel = Fuel; }
void Display( ) const
{cout << "The spaceship is at " << "("<< x << "," << y << ")." << endl; }
void FireThrusters() { x += 10; y += 10; Fuel -= 1; }
};
(8) Copy Constrctor, Assignment and Other Operators
Copy constructor:
XY(const XY& c) {
x = c.x;
y = c.y;
}
XY a(1,2);
XY b(a);
? b = a;
Assignment Operators:
const XY& operator= (const XY& e) {
x = e.x;
y = e.y;
return *this;
}
Note:
(1) function name => operator=
b.operator=(b);
(2) argument => operand
(3) "this" is a pointer generated by the compiler which always points to the current (this) object.
(4) order : object operator operand
(5) returned reference is for chaining.
XY a(1,1);
c = b = a;
? XY c = a + b;
a + b ==> a.operator+(b)
XY XY::operator + (const XY& xy) {
XY z (x + xy.x, y + xy.y);
return z;
}
XY XY::operator + (const XY& xy) { return XY(x + xy.x, y + xy.y);}
? XY c = a - b;
XY XY::operator - (const XY& xy) { return XY(x - xy.x, y - xy.y);}
? XY c = a-;
XY XY::operator - ( ) { return XY(x-, y-);}
? XY c = a * 3;
XY XY::operator * (const int dMult) { return XY(x * dMult, y * dMult);}
? a *= 3;
const XY& XY::operator* = (const int dMult) { x *= dMult; y *= dMult; return *this;}
Note: a is modified.
? XY c = 3 * a;
Global Operator: not belonging to any class.
XY operator * (const int dMult, const XY& xy) { return XY(dMult * xy.x, dMult * xy.y);}
Note:
(1) Order change : operand operator operand .
(2) Related member variables need to be public or make the global operator friend.
(9) Stack and Heap Objects
Stack objects: local objects that are not static.
Heap objects: objects allocated on the heap so that their memory remains until being specifically freed.
New & delete: (similar to malloc & free in C)
XY* pxy;
pxy = new XY(1,1);
pxy->display();
delete pxy;
pxy = new XY[64]; // cannot specify initializer for arrays
pxy[0].display();
delete [] pxy;
Note:
(1) Array deletion needs [], different from free.
(2) delete has to go with new, free has to go with malloc.
(10) Friend Classes and Friend Functions
A friend is nonmember of a class that is given access to the nonpublic members of a class.
Friend Classes
class YX {
friend class XY;
private:
int y; int x;
public:
YX() {y = x = 0; }
};
class XY {
public:
int x; int y;
void copyYX(const YX& yx) { x = yx.x; y = yx.y; }
void writeYX(YX& yx) { yx.x = x; yx.y = y; }
};
XY xy; YX yx;
xy.copyYX(yx);
Note:
(1) All member functions of XY are allowed to access any data of YX,
because YX has declared XY as a friend.
(2) Friendship can be declared to individual functions.
Friend Functions:
class YX {
friend void XY::copyYX(const YX& yx);
friend void XY::writeYX(YX& yx);
friend int tan(const YX& yx); // global
…
};
int tan(const YX& yx) { return yx.x / yx.y; }
(11) Polymorphism
Polymorphism is the ability to call a variety of functions using exactly the same interface.
Obiter o(1,1); Planet p(2,2); Spaceship s(3,3);
Obiter *a[3];
a[0] = (Obiter *) &o;
a[1] = (Obiter *) &p;
a[2] = (Obiter *) &s;
for(i=0; i<=2; i++) a[i]->Display();
/* => o.Display(); p.Display(); s.Display(); */
The orbitor is at (1,1).
The planet is at (2,2).
The spaceship is at (3,3).
Comparison of polymorphic and overloaded functions:
(1) A set of polymorphic functions have exactly the same name, same number of parameters of the same types. A set of overloaded functions have the same name but with different number or different type of parameters.
(2) A set of polymorphic functions belong to different classes of a class hierarchy. The function in the base class has to be virtual. A set of overloaded functions belong to the same class.
(3) Polymorphic functions are differentiated by the (creation) classes of the objects. Overloaded functions are differentiated by their arguments (number and type).
(12) Templets: Parameterized class definition.
Regular class definition: class Name { ... };
Regular object declaration: Name obj;
Templet definition: template <class Type>
class Name {Type ... }
Templet object declaration: Name<Type> obj;
Example: any-type array class:
template <class Type>
class Array {
public:
Type *ap;
int size;
Array(int sz) {size = sz; ap = new Type [size]; }
~Array() {delete [] ap;}
Type& operator[] (int index) { return ap[index]; }
};
Array<int> ia(4);
Array<char> ca(5);
Array<double> da(6);
e.g. Type is int.
Array<int> ia(4);
class Array {
public:
int *ap;
int size;
Array(int sz) {size = sz; ap = new int [size]; }
~Array() {delete [] ap;}
int& operator[] (int index) { return ap[index]; }
};
(13) Static Class Members
Static data members are global to the whole class rather than local to any specific object.
class XY {
public:
static int s_nCount;
int nCount;
XY() : nCount(0) { s_nCount++; nCount++;}
void Display() { cout << s_nCount << "," << nCount << endl; }
static int& GetCounter() { return s_nCount; }
};
int XY::s_nCount = 0;
void main()
{
XY u; // u.s_nCount == 1 and u.nCount == 1
XY v; // v.s_nCount == 2 and v.nCount == 1
XY w; // w.s_nCount == 3 and w.nCount == 1
u.Display(); // 3,1
v.Display(); // 3,1
w.Display(); // 3,1
}
Static Member Functions are for accessing static member data.
void main()
{
XY::GetCounter()++;
XY u, v, w;
XY::GetCounter()++;
u.s_nCount++;
v.s_nCount++;
w.s_nCount++;
u.Display(); // 8,1
}
Note:
(1) A static function can be used without declaring an object.
(2) It does not contain a "this" pointer.
(3) It cannot reference any non-static member (data or function).
(4) Non-static functions can access static members.
(14) Separating Class Definitions from Code
XY.h contains XY class definition.
XY.cpp contains XY member functions.
Class users need only check on XY.h for information.
Class authors write the functions in .cpp
Real Eyes Realize Real Lies
•
•
Join Date: Jun 2004
Location: Marin, CA, USA
Posts: 434
Reputation:
Rep Power: 5
Solved Threads: 10
Sure you can access the private members if you know how they're layed out and you are determined to be a hacker. In that case why bother with a new class anyway, why not just use a regular pointer? But, why? What if someone adds a virtual function to your demo class? Then you have a virtual function pointer at the front of the data, and the hack stops working.
Seems a whole lot easier to just (A) provide accessors, or (B) if you MUST, be a 'friend' class.
Seems a whole lot easier to just (A) provide accessors, or (B) if you MUST, be a 'friend' class.
![]() |
•
•
•
•
•
•
•
•
DaniWeb C++ Marketplace
•
•
•
•
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
Other Threads in the C++ Forum
- Previous Thread: Using x86 Assembly Language with Microsoft Visual C++
- Next Thread: which lang to choose



Linear Mode