Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 1100263
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T00:51:13+00:00 2026-05-17T00:51:13+00:00

Suppose I have a class MyClass to which I want to add certain ‘observer’

  • 0

Suppose I have a class MyClass to which I want to add certain ‘observer’ behavior. Then I could define the class like this:

class MyClass : public IObserver
{
...
};

Now suppose this this ‘observer’ functionality is not directly related to the class, but to data members stored in the class. E.g. a data member points to another class OtherClass and it needs to be set to NULL if the instance it refers to is deleted:

class PointerToOtherClass : public IObserver
{
...
};

class MyClass
{
private:
   PointerToOtherClass m_ptr;
};

In this case, we could even write this much simpler using a smart pointer.

Now suppose that instead of just putting the pointer to NULL if the OtherClass instance is deleted, we want to delete MyClass as well. So it’s not sufficient anymore to have PointerToOtherClass being an observer, MyClass should be an observer as well.
But, this means that the data member m_ptr cannot implement the full functionality (of changing its value) on its own, but also needs to put some functionality in the parent class.

A solution could be to pass a pointer to MyClass to the PointerToOtherClass member. If MyClass then implements the observer, the act of ‘registering’ and ‘unregistering’ the MyClass observer can be easily done by the PointerToOtherClass instance.

template <typename ParentType>
class PointerToOtherClass
{
public:
   PointerToOtherClass(ParentType *parent) : m_parent(parent) {}
   void setValue (OtherClass *c) { /* unregister/register m_parent */ }
private:
   ParentType *m_parent;
};

class MyClass : public IObserver
{
public:
   MyClass() : m_ptr(this) {}
private:
   PointerToOtherClass m_ptr;
};

Althoug this works correctly and can be generalized as a kind of smart pointer, we sacrifice 4 bytes (32-bit environment) because the data member needs to point to its parent. This doesn’t seem much but can be substantial if there are millions of instances of MyClass in the application, and MyClass has ten or more of these data members.

Since m_ptr is a member of MyClass, it looks like it should be possible to get the pointer to MyClass starting from a pointer to m_ptr. Or, in other words: the methods in PointerToOtherClass should be able to convert its ‘this’ pointer to a pointer to MyClass by subtracting the offset of m_ptr in MyClass.

This gave me the idea of writing this in a templated way. In the following code, the templated HostAwareField template class accesses its parent by subtracting the offset which is passed as template argument:

#include <iostream>

typedef unsigned char Byte;

template <typename ParentType,size_t offset>
class HostAwareField
   {
   public:
      ParentType *getParent() const {return (ParentType *)(((Byte *)this)-offset);}
      void printParent() {std::cout << "Parent=" << getParent()->m_name << std::endl;}
   };

class X
   {
   public:
      X (char *name) : m_name(name) {}
      char *m_name;
      HostAwareField<X,offsetof(X,m_one)> m_one;
   };

void main()
{
std::cout << "X::m_one: offset=" << offsetof(X,m_one) << std::endl;

X x1("Ross");
X x2("Chandler");
X x3("Joey");

x1.m_one.printParent();
x2.m_one.printParent();
x3.m_one.printParent();
}

However, this does not compile. It reports the following errors:

test.cpp(18) : error C2027: use of undefined type 'X'
        test.cpp(14) : see declaration of 'X'
test.cpp(18) : error C2227: left of '->m_one' must point to class/struct/union/generic type
test.cpp(16) : error C2512: 'HostAwareField' : no appropriate default constructor available
test.cpp(26) : error C2039: 'm_two' : is not a member of 'X'
        test.cpp(14) : see declaration of 'X'
test.cpp(32) : error C2662: 'HostAwareField<ParentType,offset>::printParent' : cannot convert 'this' pointer from 'HostAwareField' to 'HostAwareField<ParentType,offset> &'
        Reason: cannot convert from 'HostAwareField' to 'HostAwareField<ParentType,offset>'
        Conversion requires a second user-defined-conversion operator or constructor
test.cpp(33) : error C2662: 'HostAwareField<ParentType,offset>::printParent' : cannot convert 'this' pointer from 'HostAwareField' to 'HostAwareField<ParentType,offset> &'
        Reason: cannot convert from 'HostAwareField' to 'HostAwareField<ParentType,offset>'
        Conversion requires a second user-defined-conversion operator or constructor
test.cpp(34) : error C2662: 'HostAwareField<ParentType,offset>::printParent' : cannot convert 'this' pointer from 'HostAwareField' to 'HostAwareField<ParentType,offset> &'
        Reason: cannot convert from 'HostAwareField' to 'HostAwareField<ParentType,offset>'
        Conversion requires a second user-defined-conversion operator or constructor
test.cpp(36) : error C2039: 'm_two' : is not a member of 'X'
        test.cpp(14) : see declaration of 'X'
test.cpp(36) : error C2228: left of '.printParent' must have class/struct/union
test.cpp(37) : error C2039: 'm_two' : is not a member of 'X'
        test.cpp(14) : see declaration of 'X'
test.cpp(37) : error C2228: left of '.printParent' must have class/struct/union
test.cpp(38) : error C2039: 'm_two' : is not a member of 'X'
        test.cpp(14) : see declaration of 'X'
test.cpp(38) : error C2228: left of '.printParent' must have class/struct/union

If I change the following line:

HostAwareField<X,offsetof(X,m_one)> m_one;

to this line:

HostAwareField<X,4> m_one;

Then this code works correctly, but requires me to ‘calculate’ the offset manually, possibly leading to errors if data members are added, removed or reorganized.

This means that although I cannot automate this, I could hard-code the offsets (like the value 4 above) and perform a check (to see if 4 is really the offset of m_one in the class) afterwards, but this requires additional manual checks, making the whole system not waterproof.

Is there a way to get the source code above correctly compiled? Or is there another trick to achieve what I want to do?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T00:51:14+00:00Added an answer on May 17, 2026 at 12:51 am

    I believe a member has to be fully declared before offsetof can be used to determine its offset. This makes sense because the type of a member can affect its offset due to byte-alignment rules. (It may actually be that the entire class has to be declared first too.)

    In HostAwareField<X,offsetof(X,m_one)> m_one; the type requires offsetof to work before it can be fully declared. But offsetof requires the type to be declared before it can work. I don’t think there’s any way to make that compile.

    Offhand, I cannot think of any simple modification to this design that will make it work without needing extra bytes per member, which of course defeats the stated purpose.

    Perhaps you could revise the overall design to make the enclosing class the observer. Then have it dispatch to the appropriate member and examine some kind of return value to determine if it needs to unregister or perform whatever action is necessary on the enclosing class.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.