Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C++ (http://www.go4expert.com/forums/cpp/)
-   -   function within structures (http://www.go4expert.com/forums/function-within-structures-t18499/)

cerebrum 12Jul2009 16:43

function within structures
 
Code: C++

#include<iostream.h>
#include<conio.h>

using namespace std;

struct emp
{
    private:
       int h;

    public:
        void setdata(int a)
        {             
            h = a;
            cout<<h;
         }       
}emp1;
       
main()
{
    emp1.setdata(5);
    getch();
}

Hello there,

I wanted to know if there is any way by which I can view the emp1 member value (without omitting private specifier) like this :

cout<<emp1.h;

thanx !

SaswatPadhi 12Jul2009 18:09

Re: function within structures
 
You can simply define a public accessor function to read the value of h.
Something like :
Code: C++

void getdata()
{
    cout<<h;
}


So, your test program becomes :
Code: C++

#include<iostream.h>
#include<conio.h>

using namespace std;

struct emp
{
private:
    int h;

public:
    void setdata(int a)
    {
        h = a;
        cout<<h;
    }

    void getdata()
    {
        cout<<h;
    }
}emp1;

int main()
{
    cout << "Initialised emp1.h with : ";
    emp1.setdata(5);
    cout << endl;
    getch();
    cout << "Reading value of emp1.h : ";
    emp1.getdata();
    cout << endl;
    getch();
    return 0;
}


xpi0t0s 12Jul2009 20:32

Re: function within structures
 
(1) Within the rules: No. Private data is private data and the whole point is that you _can't_ access it unless you're a member function or a friend.

(2) Outside the rules: Yes. Just find the pointer to the object, work out the offset of h within the object and add that offset in bytes to the pointer, cast it to an int* and dereference the pointer.

Code:

struct emp
{
private:
    int h;

public:
    void setdata(int a)
    {
        h = a;
    }
}emp1;

void hackemp()
{
        emp1.setdata(5);
        int *foo=(int*)&emp1;
        // Assume offset of h is zero as it's the first thing in the class
        printf("emp1.h=%d\n",*foo);
        // Just to prove we're not cheating
        emp1.setdata(10);
        printf("emp1.h=%d\n",*foo);
}

Output:
emp1.h=5
emp1.h=10

cerebrum 12Jul2009 22:46

Re: function within structures
 
thanx both of u ! I have tried the code and it ran good , though the "offset" stuff was a bit new to me, I am trying to understand it. In the mean time I would appreciate if u "explain" it.

xpi0t0s 12Jul2009 23:21

Re: function within structures
 
Well if I can say this without sounding patronising, if you don't understand that then you should stick to the rules until you understand how this is all supposed to work. Once you get that lot, then you'll have enough knowledge to understand what I did in part 2, but if you try the advanced stuff before you get the easy stuff nailed then you'll develop loads of bad habits. For your stage, the only answer is 1: you can't, and you need an accessor function.

cerebrum 13Jul2009 00:09

Re: function within structures
 
u seem right but let me know where can i get the proper stuff to understand this. i googled but could not find anything !

xpi0t0s 13Jul2009 01:56

Re: function within structures
 
Focus on the basics first otherwise this will confuse you.

Basically structure/class members are stored as a data structure in memory, one after the other. So if you have:
Code:

class foo
{
int x;
char y[10];
double z;
};

then at an instantiation of class foo at address 1000 then **depending on how the compiler implements this**, there could be an integer at 1000, 10 chars at 1004 and a double at 1014. So to get at z without an accessor function, assuming the definition foo bar;, you would use something like char *hack=(char*)&bar; double *z_ptr=&(hack[14]);
Tried it in Visual Studio 2008:
Code:

struct emp
{
private:
    int x;
        char y[10];
        double z;

public:
        void wibble()
        {
                printf("this=0x%08lx; &x=0x%08lx; &y=0x%08lx; &z=0x%08lx\n",this,&x,&y,&z);
        }
    void setdata(double a)
    {
        z = a;
    }
}emp1;

void hackemp()
{
        emp1.setdata(5.7);
        emp1.wibble();

        char *hack=(char*)&emp1;
        double *z_ptr=(double*)&hack[16];
        printf("hack=0x%08lx; z_ptr=0x%08lx\n",hack,z_ptr);

        printf("emp1.z=%f\n",*z_ptr);
}

wibble just prints the addresses of this, x,y and z.
The first printf just checks I've worked out z_ptr correctly.
The second printf displays the value of z without using an accessor function.

Output:
Code:

this=0x00417140; &x=0x00417140; &y=0x00417144; &z=0x00417150
hack=0x00417140; z_ptr=0x00417150
emp1.z=5.700000

***THIS IS NOT PORTABLE AND IS NOT RECOMMENDED***
Use *only* if you have no other choice.
An accessor function is much better.

cerebrum 13Jul2009 03:01

Re: function within structures
 
sure, i just wanted to understand. regarding the use, i won't be using it until my basics get strengthened.
thanx a ton !

cerebrum 13Jul2009 17:03

Re: function within structures
 
int *foo=(int*)&emp1;

address of emp1 is stored in pointer foo by typecasting it to int*

I want to know why we can not assign foo the address of emp1 in this way :
int *foo = &emp1;

because emp1 is an object and not an integer variable ?

also, why can not we access the data without this typecast like :

cout<<*&emp1;

xpi0t0s 13Jul2009 17:26

Re: function within structures
 
The compiler will throw an error because it's illegal to assign a pointer-to-emp1 to a pointer-to-int. So the cast is needed to override the compiler's check. Were it not for that check then your suggested code would be fine.

NB: only use casts where you really know what you're doing. Using casts to solve compiler errors/warnings is not a good general solution.


All times are GMT +5.5. The time now is 09:56.