returning a data member's address - how?

Discussion in 'C++' started by Greg Shaw, Apr 10, 2009.

  1. Greg Shaw

    Greg Shaw Guest

    All,

    This is driving me up the wall! I have a class member which is a
    short, and I want to write an accessor method which will return a
    short* pointing to the address of that data member. It should be so
    simple, but my compiler is having none of it...

    I've tried decaring the method inline like so:

    class theClass
    {
    public:
    //.... constructors, destructor, other accessors here, then -
    short* GetMemberAddr() const
    { return &theMember;}
    private:
    short theMember;
    //....
    };

    This way, the compiler complains that the return type does not match
    what is being returned. I don't get it - the address of a short must
    be a short* .

    So I thought I'd try defining the accessor outside the class
    declaration like so -
    class theClass
    {
    public:
    //.... constructors, destructor, other accessors here, then -
    short* GetMemberAddr() const;
    private:
    short theMember;
    //....
    };

    short* theClass::GetMemberAddr()
    {
    return &theMember;
    }

    This way, the compiler complains that the definition "short*
    theClass::GetMemberAddr()" does not match the declaration "short
    theClass::*GetMemberAddr() " .

    I've tried sticking parentheses around the function name in both
    places so as to make it clear that I want it to be dealt with first
    before it's assigned to return a short* , but it doesn't work.

    Any suggestions? I think I'm going mad. And no, it isn't homework,
    it's a self-imposed learning task which I've been slogging away at for
    hours now.
     
    Greg Shaw, Apr 10, 2009
    #1
    1. Advertising

  2. Greg Shaw schrieb:
    [returning pointer to class member]
    > I've tried decaring the method inline like so:
    >
    > class theClass
    > {
    > public:
    > //.... constructors, destructor, other accessors here, then -
    > short* GetMemberAddr() const
    > { return &theMember;}
    > private:
    > short theMember;
    > //....
    > };
    >
    > This way, the compiler complains that the return type does not match
    > what is being returned. I don't get it - the address of a short must
    > be a short* .


    In a function declared const, as GetMemberAddr is, all member variables
    have a top level const added, so that they can't be modified.
    So theMember above is a "const short", effectively.

    > So I thought I'd try defining the accessor outside the class
    > declaration like so -


    It doesn't matter where you define the function.

    > class theClass
    > {
    > public:
    > //.... constructors, destructor, other accessors here, then -
    > short* GetMemberAddr() const;
    > private:
    > short theMember;
    > //....
    > };
    >
    > short* theClass::GetMemberAddr()
    > {
    > return &theMember;
    > }
    >
    > This way, the compiler complains that the definition "short*
    > theClass::GetMemberAddr()" does not match the declaration "short
    > theClass::*GetMemberAddr() " .


    One is declared const, the other non-const.

    Either let the function return a const short*, or declare the function
    non-const.

    --
    Thomas
     
    Thomas J. Gritzan, Apr 10, 2009
    #2
    1. Advertising

  3. Greg Shaw

    Greg Shaw Guest

    Both,

    Excellent, thanks, that did the trick. I don't think I would have
    worked that one out, and it will be a useful piece of syntax to
    remember in the future. Now I can return the memory address of the
    IPv4 socket in my Socket class, which is required by the connect_nw()
    function supplied in the library on the NonStop server at work. I'm
    writing a UDP client as a self-imposed learning exercise, and usually
    it's a lot of fun.

    All the best,

    Greg
     
    Greg Shaw, Apr 10, 2009
    #3
  4. Greg Shaw

    Arne Mertz Guest

    Greg Shaw schrieb:
    > All,
    >
    > This is driving me up the wall! I have a class member which is a
    > short, and I want to write an accessor method which will return a
    > short* pointing to the address of that data member.


    Why? Since you are breaking encapsulation anyway, you could make
    that data member public. Albeit neither option is good. What
    prevents you from keeping that member save inside the class by
    providing the usual clean get/set methods?

    Greets
    A
     
    Arne Mertz, Apr 11, 2009
    #4
  5. Greg Shaw

    Greg Shaw Guest

    All,

    I see what you mean about perhaps breaking encapsulation here. Maybe
    I'm designing this the wrong way. I'll tell you my reasons - the code
    on my system which deals with IP clients/servers is written in C. The
    function available to me on my system to connect from a socket accepts
    as arguments:

    1. a pointer to the start of the IPaddress
    2. an IPaddress+port length

    The IPaddress and Port variables (not the actual names I used, but you
    get the idea) are held in a C struct called Socket (for argument's
    sake).

    I don't have the expertise or access rights to change the function or
    write my own in C++, so I'm stuck with that. I did, however, fancy at
    least writing my own Socket class to hold the data members. I'm a
    relative newbie at this and enjoy the practice. So anyway, I have the
    class written, and it contains accessor methods to Get (but not set)
    the address of the IPAddress member and the combined IPAddress+port
    length. Feed them into the C function, and it should work just as if I
    were using a C struct to hold the data, is the theory (yet to be
    tested). However, I'm wondering if the better course might be to just
    use the C struct for the job at hand, and regard my class as a
    learning exercise, if I'm breaking encapsulation by providing the
    address of a data member. Ho hum.
     
    Greg Shaw, Apr 11, 2009
    #5
  6. Greg Shaw

    Arne Mertz Guest

    Greg Shaw schrieb:
    > All,
    >
    > I see what you mean about perhaps breaking encapsulation here. Maybe
    > I'm designing this the wrong way. I'll tell you my reasons - the code
    > on my system which deals with IP clients/servers is written in C. The
    > function available to me on my system to connect from a socket accepts
    > as arguments:
    >
    > 1. a pointer to the start of the IPaddress
    > 2. an IPaddress+port length
    >
    > The IPaddress and Port variables (not the actual names I used, but you
    > get the idea) are held in a C struct called Socket (for argument's
    > sake).
    >
    > I don't have the expertise or access rights to change the function or
    > write my own in C++, so I'm stuck with that. I did, however, fancy at
    > least writing my own Socket class to hold the data members. I'm a
    > relative newbie at this and enjoy the practice. So anyway, I have the
    > class written, and it contains accessor methods to Get (but not set)
    > the address of the IPAddress member and the combined IPAddress+port
    > length. Feed them into the C function, and it should work just as if I
    > were using a C struct to hold the data, is the theory (yet to be
    > tested). However, I'm wondering if the better course might be to just
    > use the C struct for the job at hand, and regard my class as a
    > learning exercise, if I'm breaking encapsulation by providing the
    > address of a data member. Ho hum.


    If I understand you correctly, you wrapped the IPaddress, port (and
    perhaps other data) in your Socket class. But to make a connection
    to the corresponding socket, your code calls the plain C function,
    giving it the pointer to your socket class' internals.

    In that situation, I'd try to give the socket class the complete
    responsibility for the C socket API by giving it a connect() method
    that calls the C function, and your code just calls that connect
    method. That way you don't have to give away handles to your class'
    internals to its client code.

    Greets
    A
     
    Arne Mertz, Apr 11, 2009
    #6
  7. Greg Shaw

    Greg Shaw Guest

    Arne,

    I think you're right. I was shying away from trying to make one class
    do too many things, but if I'm prepared to write an access method
    which gives away the address of one of its data members, I may as well
    write one which wraps up the C function call altogether.

    This is an interesting discussion, so thankyou all. It makes me think
    about the concept of privacy. After all, "privacy is not the same as
    security", so one point of view might be to say "What is wrong with
    providing the addresses of your classes' data members, so long as you
    do it via sensible Get/Set methods?" By sensible, I mean at least
    making sure that those methods maintain internal consistency within
    the class. After all, a data member may happen to be a pointer anyway
    (as may be the case when that data member would carry too much data
    for the stack, so you put the data on the heap), so we often need an
    accessor method which returns a pointer.

    As yet, I have no high hopes that any class I which I write might
    provide data security purely by putting the data just one step away
    from the stack. For me, data security is lodged way above this coding
    level, via passwords and physical barriers. So I've written an
    accessor method which would provide "unencapsulated" access to any
    client on my (supposedly secure) system which might know the internal
    structure of my class, i.e. "first AccessFamily, then Port, then
    IPAddress, so take the pointer to the first member then add the data
    length to get everything" (for example). But to me, any client which
    would use the class is already trusted. I'm not sure I really care if
    the client knows the internal structure of my class.

    So I admit that it is probably smoother to wrap up this connect_nw() C
    function in my class, and I will be happy with that, and probably
    rewrite it that way. But on a more general note, should it always be
    considered bad practice to provide accessors which return pointers to
    data members?
     
    Greg Shaw, Apr 12, 2009
    #7
  8. Greg Shaw

    James Kanze Guest

    On Apr 11, 9:44 pm, Arne Mertz <> wrote:
    > Greg Shaw schrieb:
    > > I see what you mean about perhaps breaking encapsulation
    > > here. Maybe I'm designing this the wrong way. I'll tell you
    > > my reasons - the code on my system which deals with IP
    > > clients/servers is written in C. The function available to
    > > me on my system to connect from a socket accepts as
    > > arguments:


    > > 1. a pointer to the start of the IPaddress
    > > 2. an IPaddress+port length


    > > The IPaddress and Port variables (not the actual names I
    > > used, but you get the idea) are held in a C struct called
    > > Socket (for argument's sake).


    > > I don't have the expertise or access rights to change the
    > > function or write my own in C++, so I'm stuck with that. I
    > > did, however, fancy at least writing my own Socket class to
    > > hold the data members. I'm a relative newbie at this and
    > > enjoy the practice. So anyway, I have the class written, and
    > > it contains accessor methods to Get (but not set) the
    > > address of the IPAddress member and the combined
    > > IPAddress+port length. Feed them into the C function, and it
    > > should work just as if I were using a C struct to hold the
    > > data, is the theory (yet to be tested). However, I'm
    > > wondering if the better course might be to just use the C
    > > struct for the job at hand, and regard my class as a
    > > learning exercise, if I'm breaking encapsulation by
    > > providing the address of a data member. Ho hum.


    > If I understand you correctly, you wrapped the IPaddress, port
    > (and perhaps other data) in your Socket class. But to make a
    > connection to the corresponding socket, your code calls the
    > plain C function, giving it the pointer to your socket class'
    > internals.


    If the class is called Socket, that makes sense. But there's
    also a strong argument for having a NetworkAddress class,
    containing an IPAddress and a PortAddress. (Well, maybe
    defining a class for the latter is a bit overkill.) In such
    cases, you do need some means of obtaining a pointer from
    IPAddress which can be used to call connect.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 12, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jason
    Replies:
    2
    Views:
    525
    Jonathan Mcdougall
    May 13, 2006
  2. Dwight Army of Champions

    class data member or member function argument?

    Dwight Army of Champions, Feb 21, 2010, in forum: C++
    Replies:
    4
    Views:
    1,558
    tonydee
    Feb 22, 2010
  3. eric
    Replies:
    0
    Views:
    298
  4. Stephen Howe
    Replies:
    2
    Views:
    298
    Stephen Howe
    Nov 6, 2012
  5. somenath
    Replies:
    10
    Views:
    293
    James Kanze
    Jul 2, 2013
Loading...

Share This Page