I have a homework in which:
we have this code:
#include <iostream>
using namespace std;
class Test {
int x;
char y;
public:
Test() :x(0), y(0) { ; }
};
int main() {
Test t;
//Do stuff!
return 0;
}
and without adding getters and setters or using friend class we have to read x
and y
and also change them.
I searched and found these ways:
if there was a template
function in my class I could say:
class Test {
int x;
char y;
public:
Test() :x(0), y(0) { ; }
template<typename T>
void do_something() {//not necessarily void function
//Do some stuff
};
};
class a;
// My specialization.
template <>
void Test::do_something<a>() {
cout << x << endl;
cout << y << endl;
// getting data
x = 5;
y = 'a';
// changing data
cout << x << endl;
cout << y << endl;
// getting data after changes we made
}
int main() {
Test t;
t.do_something<a>();
return 0;
}
and also the method, which I think is this question answer, is using pointers.
like this:
class Test {
int x;
char y;
public:
Test() :x(0), y('0') { ; }
};
int main() {
Test t;
int* ptr = (int*)&t;
cout << "x = " << *ptr << " y = " << (char)*(ptr + 1) << endl;
*ptr--;
//getting data
*ptr = 12;
ptr++;
*ptr = 65;
//changing data
ptr--;
cout << "x = " << *ptr << " y = " << (char)*(ptr + 1) << endl;
//getting data after changes we have made
return 0;
}
or using reinterpret_cast
and pointers:
struct pointer {
int x;
char y;
};
class Test {
int x;
char y;
public:
Test() :x(0), y('0') { ; }
};
int main()
{
Test t;
pointer* p = reinterpret_cast<pointer*>(&t);
cout << "X = " << p->x << " Y = " << p->y << endl;
//getting data
p->x = 5;
p->y = 'a';
//changing data
cout << "X = " << p->x << " Y = " << p->y << endl;
//getting data from class after changing them with pointers
return 0;
}
my questions are:
- (with pointers) why this happen?
I don't understand this one, so I will skip it.
- is such thing possible in other object oriented languages?
Consider python. In python making something private is explicitly only an agreement between the author and the user, but nothing prevents a user from accessing private members. Though, they should not. C++ isn't that explicit about saying "if you want you can access private members", but still it is possible with some effort. Nevertheless you should not. C++ does not prevent you from shooting yourself in your foot and accessing private members is one way of doing that. It isn't the case in your example, but typically accessing private members directly will break the object beyond repair.
- does this mean access modifiers are useless?
I'll repeat my comment: Is a traffic light useless? I mean when it is red I can still cross the street. Access specifiers are not there to prevent you from doing something wrong by all means, they are to help you to avoid doing something wrong (and if you try hard you can still do something wrong).
- and is there anything we can do to prevent such thing to happen?
Declaring a member as private is enough to signal that a user should not access the member directly by any means. If someone wants to break that agreement then they can do it. You cannot prevent a user from doing something wrong. If they want to break your class they can do so. However, it is not your responsibility to guarantee that something broken still works as expected. If a user bypasses access specifiers then they broke the agreement between them and you. Consider you buy a laptop and throw it out of the window from 42th floor. Will you complain to the manufacturer that afterwards the laptop is not working properly anymore? I guess no, instead you will understand that you made something wrong with using your laptop.
PS: Your last two examples are undefined behavior. reinterpret_cast
is not a way to cast between arbitrary types magically. The set of allowed casts and what you can do with the results is in fact rather limited (see here). Also a c-style cast enables you do to casts that can be very wrong, without your compiler complaining about it. Thats why they should be avoided in favor of the proper c++ casts (static_cast
et al).