Derived Structure in Derived Class??

Discussion in 'C++' started by David, Jan 27, 2008.

  1. David

    David Guest

    Hello,

    Is it possible to have a structure in a base class be expanded in a derived
    class using the same memory area. In other words:

    typedef struct tagStructA
    {
    int a,b,c;
    } sStructA;

    class CMyClass
    {
    sStructA m_StructData;
    ...
    };

    // not sure if I can typedef like this for the derived structure??
    typedef struct tagStructB : sStructA
    {
    int d,e,f;
    } sStructB;

    class CMyDerivedClass : public CMyClass
    {
    sStructB m_StructData; // using same memory location as m_StructData from
    sStructA
    ...
    };

    ??????

    TIA!!
    David, Jan 27, 2008
    #1
    1. Advertising

  2. * David:
    >
    > Is it possible to have a structure in a base class be expanded in a derived
    > class using the same memory area. In other words:
    >
    > typedef struct tagStructA
    > {
    > int a,b,c;
    > } sStructA;


    In C++ the struct name and the typedef'ed name are both types on equal
    footing, so the C++ way is

    struct A
    {
    int a, b, c;
    };


    > class CMyClass
    > {
    > sStructA m_StructData;
    > ...
    > };
    >
    > // not sure if I can typedef like this for the derived structure??
    > typedef struct tagStructB : sStructA
    > {
    > int d,e,f;
    > } sStructB;


    Just write

    struct B: A
    {
    int d, e, f;
    };



    > class CMyDerivedClass : public CMyClass
    > {
    > sStructB m_StructData; // using same memory location as m_StructData from
    > sStructA
    > ...
    > };
    >
    > ??????


    I'm almost sure someone else will comment on the abundance of question
    marks. :)

    However, to the point: physically there isn't room, and logically, at
    the design level, you're into slightly dangerous territory.

    What you can do is something like

    class Base
    {
    protected:
    typedef boost::shared_ptr<A> APtr;

    APtr myA;

    Base( APtr anA ): myA( anA ) {}

    public:
    Base(): myA( new A ) {}
    };

    class Derived: public Base
    {
    private:
    B& myB() { return static_cast<B&>( *myA ); }

    public:
    Derived(): Base( APtr( new B ) ) {}
    };

    Why this is slightly dangerous territory: consider

    struct B2: A { double x; };

    struct Derived2: public Base
    {
    private:
    B2& myB2() { return static_cast<B2&>( *myA ); }

    public:
    Derived2(): Base( APtr( new B2 ) ) {}
    };

    void foo( Base& o } { o = Derived2(); }

    int main()
    {
    Derived d;
    foo( d ); // Oops, changes contained object to B2 type.
    }

    So you'd really want to disable assignment.


    Cheers, & hth.,

    - Alf



    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Jan 27, 2008
    #2
    1. Advertising

  3. On 2008-01-27 18:18, David wrote:
    > Hello,
    >
    > Is it possible to have a structure in a base class be expanded in a derived
    > class using the same memory area. In other words:
    >
    > typedef struct tagStructA


    Skip the typedef, it is not needed in C++:

    struct sStructA

    > {
    > int a,b,c;


    };

    >
    > class CMyClass
    > {
    > sStructA m_StructData;
    > ...
    > };
    >
    > // not sure if I can typedef like this for the derived structure??
    > typedef struct tagStructB : sStructA


    struct sStructB : public sStructA

    > {
    > int d,e,f;


    };

    >
    > class CMyDerivedClass : public CMyClass
    > {
    > sStructB m_StructData; // using same memory location as m_StructData from
    > sStructA
    > ...
    > };


    No, this will give you a sStructB instance in addition to the sStructA
    instance in the base-class. What you can do is make m_StructData a
    pointer to a sStructA and initialise it with a sStructA or sStructB
    instance depending on whether you create a CMyClass or CMyDerivedClass
    object.

    --
    Erik Wikström
    Erik Wikström, Jan 27, 2008
    #3
  4. David

    Grizlyk Guest

    David wrote:
    >
    > Is it possible to have a structure in a base class
    > be expanded in a derived class using the same memory
    > area.  


    In most cases, when you treat C++ classes from desing point of view,
    this is not a question - "to share the same data by other names",
    because you refer to interfaces, without it, it is not easy to see why
    do you want to change names.

    Memory area is shared by the same types means the same members. To
    change names you need user-defined functions, like this:

    struct tagStructB : sStructA
    {
    int& d(){ return a; }
    const int& d()const{ return a; }

    int& e(){ return b; }
    const int& e()const{ return b; }

    int& f(){ return c; }
    const int& f()const{ return c; }
    };

    To hide differences between access to "a" and to "d" you need user
    defined functions of sStructA also

    struct sStructA
    {
    int& a(){ return _a; }
    const int& a()const{ return _a; }

    int& b(){ return _b; }
    const int& b()const{ return _b; }

    int& c(){ return _c; }
    const int& c()const{ return _c; }

    private:
    int _a;
    int _b;
    int _c;
    };

    There is proposal for C++ improvement, where compile time references
    can me member of class, the references can be used without overhead to
    make access to data-members, i do not remember exactly, but something
    like this

    struct tagStructB : sStructA
    {
    //they take no memory,
    //but must refer to appropriate class members only
    int& d=a;
    int& e=b;
    int& f=c;
    };

    the renaming is a kind of syntax sugar, can help you to remove extra
    standard functions.

    To change type of members you need union to be used, but instead of
    inheritance you need composition to be used

    union tagStructB
    {
    //sStructA
    int a,b,c;
    //tagStructB
    char d,e,f;
    };

    To hide improvements of sStructA you can use tepmlate<>

    template<class data=sStructA>
    class CMyClass
    {
    data m_StructData;
    ...
    };

    template<class data=tagStructB>
    class CMyDerivedClass : public CMyClass<data>
    {
    data m_StructData;
    ...
    };

    and turn them into plain code

    typedef CMyClass<tagStructB> MyClass;
    typedef CMyDerivedClass<tagStructB> MyDerivedClass;

    Maksim A. Polyanin
    http://grizlyk1.narod.ru/cpp_new
    Grizlyk, Jan 29, 2008
    #4
    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. E11
    Replies:
    1
    Views:
    4,743
    Thomas Weidenfeller
    Oct 12, 2005
  2. Victor Hannak
    Replies:
    1
    Views:
    329
    Victor Bazarov
    Aug 25, 2003
  3. Replies:
    4
    Views:
    406
    Alf P. Steinbach
    May 23, 2007
  4. Replies:
    1
    Views:
    394
    myork
    May 23, 2007
  5. Replies:
    1
    Views:
    386
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page