Access a private data member? [duplicate] - c++

This question already has answers here:
Can I access private members from outside the class without using friends?
(27 answers)
Closed 7 years ago.
Here's some code for example
class A {
int i;
}
void main()
{
A a;
}
Is there any possible (probably hackish) way to access a::i in main?
Edit:
a::i is supposed to stay private.

*reinterpret_cast<int*>(&a) = 666;
That should do the trick.
Now, technically you're causing UB by using a post reinterpret_cast variable when the types are different. But, i is guaranteed to be at the beginning of A because A is a POD.
This will absolutely not work if there are virtual functions and is not guaranteed to if you have custom constructors.
YOU SHOULD NOT EVER DO ANYTHING REMOTELY LIKE THIS!!

A very hackish way that I've used for unit testing is (WARNING: only use under adult supervision):
// In your unit test only
#define class struct
#define private public
Put this in a header file that's only used for unit testing!
EDIT: (thanks to #Peter) And only use this for quick and dirty testing - NEVER check this into a repository!

For sure this is not guaranteed to work, but it will probably work on most platforms:
#include <iostream>
class A {
int i;
public:
A (int j) : i(j) { ; }
};
int awfulGetI(A const& a);
int main()
{
A a(3);
int j = awfulGetI(a);
std::cout << "a.i=" << j << std::endl;
}
// Ugly code that may or may not work here:
struct AA {
int i;
};
int awfulGetI(A const& a)
{
struct AA const* p = reinterpret_cast<AA const*>(&a);
return p->i;
}

When creating classes, usually the point is to have the encapsulation that they provide (though, of course, you may need to retrieve or mutate the values therein). There is always the possibility of using the memory address as is demonstrated in a couple of answers here, but have you considered creating a public "getter" function in your class that simply returns the value of the variable (since the function itself has access)?
Ex.
class A {
// private:
int i = 7;
// default value used for illustration purposes.
// public:
public int getInt()
{
return i;
}
}
int main() {
A a;
int x = a.getInt(); // when called, getInt() should return 7 (in this case).
cout << x; // just to check.
return 0;
}

Related

set default parameter to a member variable [duplicate]

This question already has answers here:
How to use a member variable as a default argument in C++?
(4 answers)
Closed 1 year ago.
I tried to set a default parameter to a member variable, it gave me this bug.
[cquery] invalid use of non-static data member 'num'
code
#include <iostream>
class Test{
private:
int val = 0;
public:
void print_num(int num = val){
std::cout << num << '\n';
}
}
int main(){
Test test;
test.print_num();
return 0;
}
Despite it being quite obvious what this would mean, you just can’t. The usual workaround is to provide an overload that (implicitly) uses this to get the member value.
In order to set a default value for a function parameter to a class member, the member must be static.
Citing the documentation,
Non-static class members are not allowed in default arguments
However, given the context of your code sample I doubt this is what you want to do (as every instance of Test class will point to the same val. Citing the docs:
Static members of a class are not associated with the objects of the class: they are independent variables
If you make val static in your example, and have multiple instances of Test in use by your code, you can (and very likely will) have some unexpected behavior. Consider:
#include <iostream>
class Test{
private:
static int val;
public:
void print_num(int num = val){
std::cout << num << '\n';
}
void set_val(int num) {
val = num;
}
}
int Test::val = 0;
int main(){
Test test1;
test1.set_val(1);
Test test2;
test2.set_val(2);
test1.print_num(); // results in "2"
return 0;
}
A better alternative would be to pass a pointer to your function like this:
#include <iostream>
class Test{
private:
int val = 0;
public:
void print_num(int* numptr = nullptr){
int num = (numptr ? *numptr : val);
std::cout << num << '\n';
}
}
int main(){
Test test;
test.print_num();
return 0;
}
Or, as described by Davis Herring, use an overload:
#include <iostream>
class Test{
private:
int val = 0;
public:
void print_num(int num){
std::cout << num << '\n';
}
void print_num() {
return print_num(val); // return is irrelevant here, but my preferred coding style
}
}
int main(){
Test test;
test.print_num();
return 0;
}
Edited to reflect the comment and example.
Your function definition doesn't actually know what val is because it doesn't actually live inside of your class. The compiler is actually making a function that contains your class as a parameter and abstracts away all of that. You'll want to set num to val within the function body.

Can incorrect pointer assignment trick for add “Extension methods support” to C++ be a _problem in future?

My solution I gonna use to add “C++ Extension Methods” to JNI jobjects to make NDK code more readable like (Uniform Function Call Syntax) is:
Subclass the class that I want to add extension methods.
For invoking the “Extension Methods” make a pointer of type ExtensionsClass to point to OriginalClass - (Although the pointed object is’nt an ExtensionsClass).
The overload is minimal & we can access public methods of the Original class.
#include <iostream>
// Represents a class external to my source
class Person {
public:
Person(){
privateage = 20;
}
int age() { return privateage; }
private:
int privateage;
short anotherField;
};
class PersonExtensions : private Person {
public:
inline int size() { return 5 + age(); }
//NoFieldsOnExtensionClass
};
int main() {
Person person;
PersonExtensions* pE = (PersonExtensions*) &person;
std::cout << pE -> size() << std::endl;
std::cout << (*pE).size() << std::endl;
std::cout << sizeof(Person) << std::endl;
std::cout << sizeof(PersonExtensions) << std::endl;
return 0;
}
Do you think that this incorrect pointer assignment, since “Extension Method” only accessed public members of extended class & extension class don’t going to have any Field variables, can represent a problem in the future?
The size of the object are the same.
Thanks a lot.
This is undefined behaviour.
Yes that can break at any point.
Consider overloading ->* or something instead.
Or just using a free function.
If you really want infix notation:
template<class T, class F>
struct extension_method_t {
F f;
friend auto operator->*( T& t, extension_method_t const& self ) {
return [&t,&self](auto&&...args)->decltype(auto) {
return self.f( t, decltype(args)(args)... );
};
}
};
template< class T, class F >
extension_method_t<T,F> extension_method( F f ) {
return {std::move(f)};
}
then:
auto size = extension_method<Person>([](auto& person)->int{
return 5+person.age();
});
Person p;
std::cout << (p->*size)() << "\n"; // prints p.age()+5
here we don't have an extension method, but we do have an extension method pointer.
What you are doing in your question code is Undefined Behavior, so an especially an optimizing compiler might do really "fun" things with it. In other words, don't do it, it might break at any time even if it works when you test it. Only way to make sure it would actually work would be to examine the produced assembly code after each compilation to make sure it does what you want, and this is essentially impossible, so it is never safe.
You are using private inheritance. So for same effect you can just do this:
class PersonExtensions {
public:
PersonExtensions(Person *person) : _person(person) {}
inline int size() { return 5 + _person->age(); }
private:
Person *_person;
};
If you instead used public inheritance (so you could just call Person methods through PersonExtensions), then you'd need to add a getter for _person (for cases where real Person is needed), and/or add delegates for Person methods (for so called static polymorphism).

C++: virtual function calling parent [duplicate]

This question already has answers here:
What is object slicing?
(18 answers)
Closed 6 years ago.
#include <iostream>
using namespace std;
struct A
{
virtual int func(void) { return 0; }
};
struct B : A
{
int func(void) { return 1; }
};
int main()
{
A b = B();
cout << b.func() << endl;
}
I was expecting the output to be 1 but as most of you will know its 0.
what i want to achieve in my actual code is something along these lines.
struct A
{
virtual int operator() (int i);
};
struct B : A
{
int operator() (int i) { return i*2; }
};
struct C : A
{
int operator() (int i) { return i*3; }
};
struct x
{
A test;
};
So my container won't be able to tell before hand if it will hold a A, B or C, but should behave differently still.
Is there a way to achieve the functionality as I anticipated it work??
A b = B();: you're constructing an object of type A, using the assignment operator/copy constructor (through copy elision) from a B object, but seen as a reference to A (which explains why it compiles without errors)
This isn't polymorphism. b is still of type A. The link to B has been lost.
That would do it:
A *b = new B();
now
cout << b->func() << endl;
triggers polymorphism/virtual function and yields 1 as expected.
C++ virtual functions only works for references/pointers, which means indirections.
A b = B();
This creates an object of type A, not of type B. No indirection, therefor only the function in A is called.

getting virtual table pointer c++

I have a class such as
class Stuff
{
private:
int x;
virtual int buisness()
{
return 42;
}
public:
Stuff(){
x = 5;
}
Given a pointer to an instance of this class
Stuff stuff;
void* thing = &stuff;
How would I get a pointer to the variable x and a pointer to the virtual function table of that class using just the pointer "thing"?
Edit: to clarify this was a challenge sent to me and I have been assured that it is not a trick question.
How would I get a pointer to the variable x and a pointer to the virtual function table of that class using just the pointer "thing"?
You can't without casting thing back to the original type:
Stuff* stuff2 = reinterpret_cast<Stuff*>(thing);
and at least that doesn't redeem you from privacy policies of that class, and how you could access class member pointers publicly.
The actual layout is implementation defined, and trying to use offsets from thing and size assumptions is beyond standard c++ mechanisms.
It sounds like you want to circumvent the private member access policies of a class with known layout of these members. Here's an extremely dirty hack:
Disclamer: Don't do that in production code!!
#include <iostream>
class Stuff {
private:
int x;
virtual int business() {
std::cout << "Have that 42 ... " << std::endl;
return 42;
}
public:
Stuff() {
x = 5;
}
};
struct StuffProxy {
// Make the layout public:
int x;
virtual int business();
};
int main() {
Stuff stuff;
void* thing = &stuff;
// Here's the nasty stuff
StuffProxy* stuffProxy = reinterpret_cast<StuffProxy*>(thing);
int* addrX = &(stuffProxy->x); // Get the address of x
std::cout << "x = " << *addrX << std::endl;
typedef int (Stuff::*StuffFunc)();
StuffFunc stuffFunc = (StuffFunc)(&StuffProxy::business);
std::cout << "business() = " << (stuff.*stuffFunc)() << std::endl;
}
Output:
x = 5
Have that 42 ...
business() = 42
Live Demo
The above works because it's guaranteed that class and struct will have the same layout in a c++ compilers implementation, with the only difference of the members visibility during compilation.
So if you have the layout of a class (e.g. from a header), and you are willing to maintain that over the lifetime of your project, you can provide such proxy like above to access the private stuff from a class.
To access the private member x:
1) Declare the function, that needs to access x, as a friend of the class.
2) Change access to public.
3) Write public getter or setter functions.
4) Change your design; Other classes should not know about member variables.
This may be compiler dependant.
I just made a char array from the pointer "thing"
char *array;
array = (char*)thing;
Then traverse that array until I found the private variables
int x = array[8];

Why can't a class have same name for a function and a data member?

Why can't a c++ class have same name for a function and a data member?
class demo{
public:
int size();
private:
int size;
};
int main(){
return 0;
}
C:\Users\S>g++ demo.c
demo.c:5:7: error: declaration of 'int demo::size'
demo.c:3:7: error: conflicts with previous declaration 'int demo::size()'
Suppose you want to take the address of the member-function size(), then you would write this:
auto address = &demo::size;
But it could be very well be the address of the member-data size as well. Ambiguous situation. Hence, it is disallowed by the language specification.
That is not to say that it was impossible for the C++ committee to come up with a solution, but I suppose there is no major gain in doing so. Hence, the Standard simply disallowed it, to keep things simple.
Also, the difference between member-data and member-function becomes less distinguishable visually if one declares the member function size() as:
typedef void fun_type();
struct demo
{
fun_type size; //It looks like a member-data, but it's a member-function
};
void demo::size() //define the member function
{
std::cout << "It is crazy!" << std::endl;
}
int main()
{
demo d;
d.size(); //call the function!
}
Output:
It is crazy!
See the online demo : http://ideone.com/ZjwyJ
Now if we can implement member functions as explained above, then it becomes too obvious even to the naked eye that you cannot add another member with same name as:
struct demo
{
fun_type size;
int size; //error - choose a different name for the member!
};
Wait That is not entirely correct, as the story is not finished yet. There is something less obvious I need to add here. You can add more than one member with same name:
typedef void fun_type0();
typedef void fun_type1(int a);
typedef void fun_type2(int a, int b);
struct demo
{
fun_type0 member; //ok
fun_type1 member; //ok
fun_type2 member; //ok
};
This is completely valid code, as each member is a function of different type, so you can define them as:
void demo::member()
{
std::cout << "member()" << std::endl;
}
void demo::member(int a)
{
std::cout << "member(" << a << ")" << std::endl;
}
void demo::member(int a, int b)
{
std::cout << "member(" << a << ", "<< b << ")" << std::endl;
}
Test code:
int main()
{
demo d;
d.member();
d.member(10);
d.member(200,300);
}
Output:
member()
member(10)
member(200, 300)
Online Demo : http://ideone.com/OM97Q
The conclusion...
You can add members with same name, as long as they're function of different types. This is enabled by a feature called member-function-overloading (or simple function-overloading)1.
1. Unfortunately, the language doesn't provide similar feature, say member-data-overloading, for member data, neither do the language provide cross-member-overloading (that allows member-data and member-function to have the same name — the case in the question).
So here a question naturally arises: do they not cause ambiguity problem? Yes, they do. But the point to be noted is that C++ committee came up with a solution to solve this ambiguity-problem, because they saw a huge gain in doing so, (in case of function-overloading).
But the case in the question remains ambiguous, as the committee didn't come up with a solution, as they didn't see any huge advantage in doing so (as noted before). Also, when I said "C++ committee came up with solution", I do NOT mean that the solution has been Standardized, I merely mean that they knew how the compilers can solve it, and how complex the solution would be.
because if you use size in your class somewhere then the compiler does not know what to do. It can be either the int-data-member or it can be the function-pointer. So the compiler is not able to seperate both kind
As an example (Not maybe the best but it might explain it visually):
class Size {
std::size_t size_;
public:
Size(std::size_t s = std::size_t() ) : size_(s){}
std::size_t operator()() const {
return size_;
}
void operator()(std::size_t s) {
size_ = s;
}
};
class Demo {
public:
Size size;
};
int main() {
Demo d;
d.size(10);
std::size_t size = d.size();
return 0;
}
Basically the variable could be callable as well. So there is no way for the compiler to know your intentions.
Of course this is defined by the language that it shall not be possible to have the same name as identifier within the same scope.