473,657 Members | 2,667 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Pointer to data member vs. offsetof


Hi

I know that offsetof is basically a C leftover, and only works for POD
types, not classes, so it is recommended that I use pointers to
members instead. However, I have a problem where I don't see how I
should use pointers to members.
Basically, I know how to get a member if I have an object and a
pointer-to-member (obj.*ptr instead of obj + offset), but I don't know
how to do the opposite: getting the object from a member address and a
pointer-to-member (that is, what to write instead of member - offset).

Here's what I need it for:

I have a class, for now let's just call it Outer. It has a member
variable, the type of which is a class called Inner. Inner has a
function F(). In F(), I need to have an Outer* pointer that points to
the Outer object that contains this Inner object.

class Inner
{
public:
virtual ~Inner() {}
void F();
};

class Outer
{
public:
Inner inner;
};

void Inner::F()
{
Outer* parent = ???;
}

Of course, a pointer to the parent Outer object could be passed to F()
as an argument, or as a constructor argument when creating
Outer::inner, but it seems to be unnecessary. In every Outer object,
the Inner object is at the same offset (this is guaranteed, isn't
it?), so we should be able to calculate the address of the the parent
Outer in Inner::F().

I can do this on compilers where offsetof is supported for classes as
well as PODs, but I'd like to know if there's a more portable
solution.

Thanks,

Imre

Apr 21 '07 #1
2 3914
On 21 Apr 2007 12:12:51 -0700 in comp.lang.c++, Imre <im****@pager.h u>
wrote,
>Of course, a pointer to the parent Outer object could be passed to F()
as an argument, or as a constructor argument when creating
Outer::inner , but it seems to be unnecessary.
Yes, it's necessary. Otherwise Inner doesn't even know if it is living
inside an Outer object, or created stand-alone.

Apr 22 '07 #2
On Apr 22, 4:20 am, David Harmon <sou...@netcom. comwrote:
On 21 Apr 2007 12:12:51 -0700 in comp.lang.c++, Imre <imr...@pager.h u>
wrote,
Of course, a pointer to the parent Outer object could be passed to F()
as an argument, or as a constructor argument when creating
Outer::inner, but it seems to be unnecessary.

Yes, it's necessary. Otherwise Inner doesn't even know if it is living
inside an Outer object, or created stand-alone.
True, but Inner could know about where it's living without passing in
the parent object; for example, using a template parameter to pass in
the parent _type_. Passing around object instances still seems to be
overkill (and either overhead (storing a parent pointer in Inner) or
inconvenience (always passing in parent to Inner::F())) to me.
Here's a more complete solution using offsetof:

// Empty primary template, see specializations below
template <typename Outer, int Id = 0>
struct InnerOffset
{
};

template <typename Outer, int Id = 0>
class Inner
{
public:
Outer* F();
};

template <typename Outer, int Id>
Outer* Inner<Outer, Id>::F()
{
return (Outer*)(((char *)this) - InnerOffset<Out er, Id>::offset);
}

// ---

class Outer1
{
public:
int i;
Inner<Outer1inn er;
};

template <>
struct InnerOffset<Out er1>
{
enum { offset = offsetof(Outer1 , inner) };
};

//

class Outer2
{
public:
int i, j;
Inner<Outer2, 0inner0;
Inner<Outer2, 1inner1;
};

template <>
struct InnerOffset<Out er2, 0>
{
enum { offset = offsetof(Outer2 , inner0) };
};

template <>
struct InnerOffset<Out er2, 1>
{
enum { offset = offsetof(Outer2 , inner1) };
};
int main(int argc, char* argv[])
{
Outer1 o1;
Outer1* po1 = o1.inner.F();
assert(po1 == &o1);
Outer2 o2;
Outer2* po20 = o2.inner0.F();
assert(po20 == &o2);
Outer2* po21 = o2.inner1.F();
assert(po21 == &o2);
return 0;
}

Here no memory is wasted by storing a pointer to the parent object in
every Inner, and also we don't need to always pass the parent object
to Inner::F(). But still, Inner members can be used in whatever Outer
class we like, and they can find their parent. Even multiple Inner
members in the same Outer class are supported.
The only problem is that this code uses offsetof on classes, and that
isn't guaranteed to work on all compilers.

So the question is: is it possible to do the same in a more portable
way? That is, without offsetof. Using pointers to data members, or
whatever.

Imre

Apr 22 '07 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
380
by: mk | last post by:
In C++ one can get an absolute address of data member, having a pointer-to-member and a pointer to class object: struct A { int m; }; void f(A *a) {
40
3006
by: Steve Rencontre | last post by:
I can't for the life of me see how to do pointer-to-member when the member is actually part of an embedded structure. That is, if I have: struct S1 { int a; }; struct S2 { S1 s; int b; }; how can I get a pointer to the a in an S2?
5
5100
by: Angel Tsankov | last post by:
Does the standard define what happens when a NULL pointer is dereferenced? If so, where?
6
1760
by: sieg1974 | last post by:
Hi, Given a pointer to a member within a struct, is it possible to determine the pointer to the structure? If so, how can it be done? Thanks, Andre struct Structure
10
2204
by: haomiao | last post by:
I want to implement a common list that can cantain any type of data, so I declare the list as (briefly) --------------------------------------- struct list { int data_size; int node_num; char nodes; //will be list_node1,list_node2... };
5
1444
by: pete142 | last post by:
Hi folks -- I have a 4-long array t of of struct Targets. And a table of int * in p. I need to set up the int * entries in p such that each can reference an int in any member of the Targets t array. How to do it?
14
2784
by: ManicQin | last post by:
Hi all. I'm trying to get the size of a variable in a struct by his relative postion i.e. /// #define offsetof(s,m) (size_t)&(((s *)0)->m) struct ThePimp{ char rings; char blings;
9
3714
by: shaun roe | last post by:
Question about pointer-to-data members I have a deeply nested loop, the innermost bit looks a little like this: for(it(vec.begin(), end(vec.end()), it!=end;++it){ if (global == 0){ myObj = it->func().second->anObj(); } else { myObj = it->func().first->anObj(); }
22
3231
by: sivadhanekula | last post by:
Hello Everyone A quick and direct question: I need a C/C++ program to extract the data from the database and the output should be in CSV "Comma Separated Value" format. Briefly: I will be given a database and my work is to extract a particular data from that whole database and should get a output in CSV format. The database given to me has 24 tables and I need to extract data from any one of the table and if I press the run button I should...
0
8402
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
1
8508
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8608
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5633
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4164
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4323
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2733
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1962
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1627
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.