How does Data Encapsulation actually happen in OOP? - c++

I'm learning C++.
Came across data encapsulation and data hiding at a website, check out the following piece of code:
#include<iostream.h>
#include<conio.h>
class sum {
private: int a, b, c;
public:
void add() {
clrscr();
cout << "Enter any two numbers: ";
cin >> a >> b;
c = a + b;
cout << "Sum: " << c;
}
};
void main() {
sum s;
s.add();
getch();
}
NOW. As it says here that:
The main advantage of using of encapsulation is to secure the data from other methods, when we make a data private then these data only use within the class, but these data not accessible outside the class.
What happens underneath the code, what does the compiler do that makes it inaccessible to other classes? And in the given example what was the reason behind defining a,b and c as private.
What were they trying to achieve by hiding "just the declarations of the three variables"? Because anyone can see that inside public three numbers being used are a,b, and c - first two for input and third one for output.

How is this possible that the data under private can't be accessed
outside the class?
Compiler makes sure you don't. If you try to access say a outside class, your code will not compile.
And in the given example what was the reason behind defining a,b and c
as private.
It could be anything! But as a result, a,b and c are not accessible outside members of class.
Basically you want to hide some variables in your class for the sake of consistency. So that you or your clients can not produce a code that makes unwanted and uncontrolled changes.
Updates:
What happens underneath the code, what does the compiler do that makes
it unaccessible to other classes?
Compiler implementation check for access level while producing code. If there is something wrong, you will get a syntax error and no machine code will be generated from your file.
And in the given example what was the reason behind defining a,b and c
as private; what were they trying to achieve by hiding "just the
declarations of the three variables"? Because anyone can see that
inside public three numbers being used are a,b, and c - first two for
input and third one for output.
You don't hide variables in your class to make them invisible to others. Private variables that are not intended to be used from outside of the class can be marked as private to limit the potential for coding errors.
As an example consider following class:
class rectangle {
public:
int width;
int height;
int area;
};
void something_important(const rectangle& r) {
// ...
}
What happens if I pass a rectangle of width -10, height 0 and area of -15? There could be a plane crash or a nuclear weapon launched to some wrong target... So I will make sure my rectangles are always valid:
class rectangle {
public:
void set_width(int w) {
if(w) width = w;
else width = 0;
area = width*height;
}
int get_width() const {return width;}
void set_height(int h) {
if(w) height = h;
else height = 0;
area = width*height;
}
int get_height() const {return height;}
int get_area() const {return area;}
private:
int width;
int height;
int area;
};
So no one can make a rectangle of negative height or width, and no one can make a rectangle having a wrong area. (you can not actually change area directly)
I hope it makes sense for you now.

What happens underneath the code, what does the compiler do that makes it unaccessible to other classes?
Not much. The compiler doesn't protect against access to the data. It protects against access to the name of the data. For instance:
void foo(class bar&, int&);
class bar {
int i = 0;
public:
void baz() {
foo(*this, i);
}
};
void foo(class bar& b, int& i) {
//b.i = 42; // This is an error. b.i is private
i = 42; // This is okay, no matter what the local i refers to
}
In the example above, foo() cannot access b.i by name, because it's a private data member. But it can still modify it if it obtains a reference by other means. The member function baz() which has access to that name, binds it to the reference that foo() accepts. Thus allowing for its modification from outside the class's scope.

Related

Accessing a class variable in another class shows a different behavior in C++

I am a newbie in C++. Here in my case I have created two classes, class One and class Two. _x is declared as a private member variable of class One. So here I am trying to learn different methods to access this private variable(_x) from any other class(Here in this case it is class Two). This is my scenario basically. So one method I tried is ,making class Two as a friend class of class One and for accessing this variable, I have used directValOfOne function to print the value of this variable and another one I tried was passing the address of the class One instance in another member function (getDataTwo) of class Two. Everything works well until here.
As you can see, I have initialized the _x using a parameterized constructor and printing this variable gives me the value as 10 using both the methods. Again I modified this variable using a
setter function (setDataOne) to 220 and when I print it using the getDataTwo function it prints the value as 220. But when I tried to print the value using directValOfOne, it still showing the old initialized value (10) which I am really confused. I have printed the address of class One object in this directValOfOne funtion and it shows same. If so then why the new value(220) is not updated here.
Source code is placed below.
#include <iostream>
using namespace std;
class One{
int _x;
public:
One(int a):_x{a} {}
//setters and getters
void setDataOne(int a) { _x = a; }
int getDataOne() const { return _x; }
//print values
void printOne() { cout<<"_x - "<<_x<<endl; }
friend class Two;
};
class Two{
One _a;
int id_one = 0;
public:
Two(One a):_a{a} {}
//setters and getters
void setDataTwo(int a) { }
int getDataTwo(One *obj) {
id_one = obj->getDataOne();
return id_one;
}
void printTwo() { printf("id_one = %d\n",id_one); }
void directValOfOne() {
printf("address = %p\n",&_a);
printf("_a._x = %d\n",_a._x);
}
};
int main(){
One one(10);
Two two(one);
one.printOne();
two.getDataTwo(&one);
two.printTwo();
two.directValOfOne();
printf(" *********** \n");
one.setDataOne(222);
one.printOne();
two.getDataTwo(&one);
two.printTwo();
two.directValOfOne();
return 0;
}
and the console output is,
_x - 10
id_one = 10
address = 006dfee4
_a._x = 10
***********
_x - 222
id_one = 222
address = 006dfee4
_a._x = 10
As you can see the _a._x still prints the value 10. But actually the _x is updated to new value 220. Sorry if I explained it so detail. Just to give you an overview I detailed like this.
So my que is ,
Why it is not showing the updated value since the addresses are same?
Am I missing any important concept here ? If so please guide me to understand this problem.
The problem in your code is that you pass to Two an instance of class One by value. This means that Two stores a copy of the instance of One you pass to it. When you change the value of _x in one it does not affect the value of _x in _a (inside two).
In order for your code to work you need to pass a reference to One in Two's constructor and store this reference. Now every change to one will also affect _a.
Modified code:
class Two{
One& _a;
int id_one = 0;
public:
Two(One& a):_a(a) {}
// ...
Regarding the address issue, the address of _a will stay the same since there's no reason for it to change once initialized. If you'll print the address of one in your current code (before the suggested modifications) it should be in a different address than _a (since _a is a copy that's located somewhere else).
In the modified version of the code you should see the same address since it's the same object.

Instantiate only one class at a time, out of a group of classes, to save memory

The following is directly related to this. What I would like is to be able to call and have active only one class at a time, to save memory, but also because I plan to add, later on, a GUI, so I'd be able to call the classes through a drop-down menu (for example).
I tried making composition, and this is what came out:
#include <iostream>
class Power
{
private:
double m_x;
public:
Power() {std::cout<<"Power\n";}
Power(double x): m_x {x} {std::cout<<"Power("<<x<<")\n";}
~Power() {std::cout<<"~Power\n";}
const double getX() const { return m_x; }
};
class Scanner
{
private:
Power m_power;
public:
Scanner() {std::cout<<"Scanner\n";}
Scanner(const Power &p): m_power {p} {std::cout<<"Scanner("<<&p<<")\n";}
void print() {std::cout<<"x="<<m_power.getX()<<'\n';}
};
class Printer
{
private:
Power m_power;
public:
Printer() {std::cout<<"Printer\n";}
Printer(const Power &p): m_power {p} {std::cout<<"Printer("<<&p<<")\n";}
void print() {std::cout<<"x="<<m_power.getX()<<'\n';}
};
class Copier // if Copier is to be used for "unification", will "public" be needed?
{
private:
Scanner *m_s;
Printer *m_p;
int m_i;
public:
Copier() {std::cout<<"Copier\n";}
Copier(const Power &p, int i): m_i {i}
{
if (i)
m_s = new Scanner(p);
else
m_p = new Printer(p);
std::cout<<"Copier("<<&p<<","<<i<<")\n";
}
void print() { std::cout << (m_i ? m_s->getX() : m_p->getX()) << '\n'; }
};
int main(int argc, char *argv[])
{
Scanner *s {new Scanner(Power(2.3))};
s->print();
Printer *p {new Printer(Power(3.14))};
p->print();
s->print(); // here, both *s and *p exist, both use memory
// this comes after considering adding class Copier
Copier *c {new Copier(Power(1.618), 0)};
c->print();
c = new Copier(Power(2.718), 1);
c->print();
return 0;
}
Ignore Copier for a bit. As it is, I can use it, and this is what comes out:
Power(2.3)
Scanner(0x7ffc80d98c10)
~Power
x=2.3
Power(3.14)
Printer(0x7ffc80d98c20)
~Power
x=3.14
x=2.3
The (major) problem now is that there are multiple objects in memory, there's *s and there's *p, as you can see x can pe printed out with both 3.14 and 2.3. If I have more than 2 classes (which I do), I could call each class and each will take up memory. That's not something I want.
How can I call only one class at a time and not have to call extra resets or deletes? I thought of adding another class for it, see Copier. But I can't use std::unique_ptr and the solution in the code is, not only extremely ugly, but doesn't even work. Plus it calls constructors like crazy.
I tried using std::unique_ptr in a simple function, with std::make_unique (that needs c++14, and I'd rather keep some larger safety margin, but I could also live with it, too). It also doesn't work because it points to Power (if I call z->print() it says 'class Power' has no member 'print'):
std::unique_ptr<Power> call(const Power &p, const int &i)
{
if (i)
return std::make_unique<Printer>(p);
else
return std::make_unique<Scanner>(p);
}
I don't know how to make this. In short, classes Scanner, Printer, and any other that exist, are dedicated classes that perfom one task, only, unique in their way of computing, and all of them make use of some common variables in Power (besides their own). I don't think it would be very effective to move the common variables to each class because they would only bloat the code, and, as I understand it, "if you can use a storage class instead of repeating the same variable over and over, use it" (not my words, is this true?). Then, I'd like to be able to instantiate those classes, but only have one active at a time, to spare memory.
As an example, suppose one class makes an array of 1mil values, then another makes 1mil different values, and so on. Imagine having that array in memory as many times as there are instantiated classes. I don't want that. The purpose of Copier would have been to call (based on the conditional) only one class at a time. Job done? Call another, but forget anything else that was done before, start anew. And all this to be able to call through only one widget, such as select from list, click&go, that will be added later.
That was a stupid mistake, I forgot to delete public ... after copy-pasting. I also tried the code now (with Copier), it compiles, but still doesn't work, m_x stays empty, even with the very ugly solution of having two Scanner and Printer pointers as member variables inside Copier.
Well, after some tries, I couldn't make what I wanted so I thought to go back to my original idea, even if it meant inheritance. So I came up with this piece of code, where I changed the names to make a bit more sense(?):
#include <iostream>
class Garage
{
protected:
double m_x; // gas, tires, etc, that all cars use, reside in the Garage
public:
Garage() {std::cout<<"Garage\n";}
virtual ~Garage() {std::cout<<"~Garage\n";}
};
class Audi: virtual public Garage
{
public:
Audi() {std::cout<<"Audi\n";}
void f(const double &x) { m_x=x; std::cout<<"Audi::f("<<x<<")\n";}
};
class Bmw: virtual public Garage
{
public:
Bmw() {std::cout<<"Bmw\n";}
void f(const double &x) { m_x=x; std::cout<<"Bmw::f("<<x<<")\n";}
};
class Driver: public Audi, public Bmw
{
private:
double m_y; // report of driving, based on m_x
public:
Driver() {std::cout<<"Driver\n";}
Driver(const double &x, int i)
{
if (i)
Bmw::f(x);
else
Audi::f(x);
m_y = -m_x;
std::cout<<"Driver("<<x<<","<<i<<")\n";
}
void print() { std::cout << "x=" << m_x << ", y=" << m_y << '\n'; }
};
int main(int argc, char *argv[])
{
Driver *d {new Driver(1.618, 0)};
d->print();
d = new Driver(0.618, 1);
d->print();
// even iteration works now
delete d;
d = nullptr; // to be sure it's dead(?)
for (int i=0; i<2; ++i)
{
d = new Driver(3.14, i);
d->print();
}
return 0;
}
Now, this works, but I have a feeling I set a new record on bad code example. Please don't bash me for this, rather point out all the mistakes, or how you would do it to achieve the same result. Still, even if it seems to work as I want, it still calls all the constructors, on all branches, instead of only on the needed ones. I realize (my apologies) I forgot to say that Driver, here, is also responsible for using m_x further, for its m_y (that's why the code is a bit different).
I'd like to point out that I am not fixed in keeping this code, or any other, I am willing to change and adapt, as long as I reach my purpose. But since I am a beginner, I can't make too many combinations, so I am left with presenting whichever result it is that I reached to try and make myself understood. The program above, as it is, when run, gives what I want, even has the possibility of making a loop, which will let me use it much easier in a GUI, later on. The names, as they are, make the most sense in composition, Garage has-a Bmw, and that was what I tried, but I couldn't obtain what I wanted. So, even if this uses inheritance and does not make sense that an Audi is-a Garage, I kept the names to suggest my initial tryout with composition. My main reason for posting this is to show what I would like the program to do. What happens in main() will be used in a GUI, I am thinking of Qt, because I'd like this to run on all 3 major OSes. So having the possibility of calling one car at a time, using it, and also being able to store previous information without having stale objects in memory, only m_x*nr_of_cars, will make it much easier to work with.
Here is one way to do it.
{ // scope begins
Printer p; // note, no pointers
p.print();
} // scope ends, p is gone
Here we have an object that appears, does one thing once, and disappears.
Here is another
boost::variant<Printer,Scaner,Copier> psc(Printer());
psc.get<Printer>().print();
psc = Scaner(); // the printer is gone
Use some std::unique_ptr constructor:
std::unique_ptr<Power>
call(const Power &p, const int &i) {
if (i)
return std::unique_ptr<Power>(new Printer(p));
else
return std::unique_ptr<Power>(new Scanner(p));
}
Perhaps what you really want is a tagged union. Follow the rule of five. See this for inspiration.

What is the difference between using the friend keyword, and using a member function to modify private variables inside of a class?

As the question asks...
What is the difference between:
class MyClass
{
public:
MyClass(){
m_a = 0;
}
private:
int m_a;
friend void set_a(MyClass &a);
};
void set_a(MyClass &a)
{
std::cout << a.m_a << std::endl;
a.m_a = 500;
std::cout << a.m_a << std::endl;
}
int main(void) {
MyClass my_class_instance;
set_a(my_class_instance);
system("pause");
}
and:
class MyClass
{
public:
MyClass(){
m_a = 0;
}
void set_a(){
std::cout << this->m_a << std::endl;
this->m_a = 500;
std::cout << this->m_a << std::endl;
}
private:
int m_a;
};
int main(void) {
MyClass my_class_instance;
my_class_instance.set_a();
system("pause");
}
Is it simply the preferred structure of the function, or are there real, measurable differences? From what I can tell, both functions achieve the same results in all circumstances, except if you had multiple overloads for the first example, that took different types of objects.
As the C++ FAQ says: Use a member when you can, and a friend when you have to.
There are situations where making friend a free function is preferable, most situations related to the fact that the first parameter of a member function is always of that class (Its the hidden *this parameter).
One example is arithmetic operators overloading:
Suppose you write a complex class which represents complex numbers. Using a member operator+() you could write expressions like complex + float, but not float + complex. But you could do it with the free form of the operator+:
class complex
{
...
friend complex operator+( float f , complex c );
};
This whole question comes down to "Why would I use friends in C++?". The answer is that when used properly, friends enhance encapsulation. This is an FAQ:
Do friends violate encapsulation?
Your example is too short and too abstract, of course. Some better, real life examples I could think of from the top of my head involve iterators. You may have many iterator objects referring to only one container object, and you may want the iterator to be able to access private member variables of the container. At the same time, you don't want the container to expose those variables to the rest of the world.
Such a design could be perfectly implemented with the friend feature.
Many people defend that making accessor methods, you can in a later stage of development put barriers to the incorrect access to the member variables (or even change the member variables totally) without breaking your (correct) clients.
One classical case is of a
class ComplexNumber {
double real, imaginary;
public:
double re() { return re; }
double setRe(double v) { return re = v; }
// and so on ...
};
one day you discover, in some maintenance, that you need the polar coordinates for that number, so you add the methods
double rho() { /* calculate rho */ }
double theta() { /* calculate theta */ }
double setRho(double v) { /* calculate real, imaginary, based on the new rho */ }
and so on.
Later yet, you discover that the users of the class use far more often polar than Cartesian coordinates for complex numbers, and that the conversions have been the bottleneck of a performance problem, so you ditch real and imaginary and store rho and theta, and change the getter and setter methods for the new -- more efficient -- storage for rho, theta, re, im, and so on. All the clients of your class will recompile without problems, because you changed your implementation but kept your interfaces stable.

Working with objectives and calling methods?

I've probably become a bit to used to Java and am finding this harder than it should be. Heres what I have.
myObject[0] = new item1(this);
class item1
{
private:
int x;
int y;
public:
item1( passedPointer* pOne )
{
x = 5;
y = 5;
}
int returnX() { return x; }
int returnY() { return y; }
}
Then in another method I thought I could just say:
void check()
{
int y = item1.returnY();
int x = item1.returnX();
}
But I am getting the common error: a nonstatic member reference must be relative to a specific object.
There is only one instance of this class item1, what would be the best way to do this? This is just a simplified fragment of what I'm actually doing, not the actual code.
Item1 is a class. You have to create an instance of it before you can access its non-static members. Try looking here for some basic information.
void check(){
int y = item1.returnY;
int x = item1.returnX;
}
This would also be incorrect in Java, since neither returnX nor returnY are statics, you need an object on which to apply the operation, and you also need the parenthesis of the method call:
void check() {
item1 i;
int y = i.returnY();
int x = i.returnX();
}
Perhaps implementing the Singleton pattern would not do you harm, since you want only one instance of the object. You could declare the object as global or static to a function too, then get the values.
Then again, you could also declare the functions as static, and add another one to initialize the static values of the variables which need to be returned by those methods. There are a lot of solutions to this depending on your situation which can not be fully grasped by the short amount of code you have pasted.
You created an instance of class item1 with the line
myObject[0] = new item1(this);
Unlike JAVA, in C++ there are pointers and new returns a pointer to the object (so myObject[0] is a pointer to the instance) so you need the -> operator. To activate the method you should write:
myObject[0]->returnX();
If you wish to have only one instance than implement the class as a singleton.

'this' pointer, inheriting functions of super class in subclass using 'this' pointer

Hi i am trying to understand how to use the 'this' pointer. Now i wrote a sample program which uses a class Image which is a subclass of a class BMP. Now the functions TellWidth and TellHeight are declared in the BMP class. Now the compiler gives me an error which says that the TellWidth function does not exist in Image. But as Image is a subclass of BMP shouldnt it inherit the functions in BMP.
How do i resolve this
void Image :: invertcolors()
{
int x;
int y;
int width =(*this).TellWidth();
int height = (*this)->TellHeight();
for(x=0,x<=height-1;x++){
for(y=0,y<=width-1;y++){
(*this)(x,y)->Red = (255 - (*this)(x,y)->Red);
(*this)(x,y)->Blue = (255 - (*this)(x,y)->Blue);
(*this)(x,y)->Green = (255 - (*this)(x,y)->Green);
}
}
delete width;
delete height;
}
Image
class Image : public BMP
{
public:
void invertcolors();
void flipleft();
void adjustbrightness(int r, int g, int b) ;
};
This class is too big to post here, here is a relavent excerpt
class BMP {
private:
int Width;
int Height;
public:
int TellBitDepth(void) const;
int TellWidth(void) const;
int TellHeight(void) const;
};
TellWidth() is most likely declared as private (or has no accessor modifier) in the BMP class. It needs to be protected or public for the Image class to be able to access it, and it needs to be also virtual, if you want to be able to override it in the Image class.
And the proper this usage is like this:
int width = this->TellWidth();
int height = this->TellHeight();
Read this for a quick tutorial on this.
One point about this: you rarely need to mention it explicitly. The usual exception is when you need to pass it into a non-member function (which doesn't seem to be the case here.)
When you're inside of a class member function, this->field can be accessed simply as field, and this->function(x) can be invoked as function(x).
Here are some comments on your code. I hope they're helpful.
void Image :: invertcolors()
{
// Don't define these here; that's old C-style code. Declare them where
// they're needed (in the loop: for (int x=0...)
int x;
int y;
// Change the lines below to
// int width = TellWidth();
// int height = TellHeight();
// (*this).TellWidth() should work, but is redundant;
// (*this)->TellHeight() should probably *not* work, as once you've
// dereferenced *this, you're dealing with an object instance, not a
// pointer. (There are ways to make (*this)->that() do something useful,
// but you're probably not trying something like that.)
int width =(*this).TellWidth();
int height = (*this)->TellHeight();
for(x=0,x<=height-1;x++){
for(y=0,y<=width-1;y++){
// After locating the BMP class through google (see Edit 2),
// I've confirmed that (*this)(x,y) is invoking a (int,int) operator
// on the BMP class. It wasn't obvious that this operator
// was defined; it would have been helpful if you'd posted
// that part of the header file.
(*this)(x,y)->Red = (255 - (*this)(x,y)->Red);
(*this)(x,y)->Blue = (255 - (*this)(x,y)->Blue);
(*this)(x,y)->Green = (255 - (*this)(x,y)->Green);
}
}
// These are int values. They can't be deleted, nor do they need to be.
// I'm sure the compiler has told you the same thing, though perhaps not
// in the same way.
delete width;
delete height;
}
EDIT: Looks like there's someone else taking the same course as the OP. The example presented there makes it clearer that Image is supposed to have some sort of array accessor, which may explain what (*this)(x,y)->Red = (255 - (*this)(x,y)->Red) was intended to achieve.
EDIT 2: Here's the source for the original BMP class.
class Image is defined as
class Image : public BMP
{
public:
void invertcolors();
void flipleft();
void adjustbrightness(int r, int g, int b) ;
};