returning a data member's address - how?

G

Greg Shaw

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.
 
T

Thomas J. Gritzan

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.
 
G

Greg Shaw

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
 
A

Arne Mertz

Greg said:
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
 
G

Greg Shaw

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.
 
A

Arne Mertz

Greg said:
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
 
G

Greg Shaw

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?
 
J

James Kanze

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top