Derived Structure in Derived Class??

D

David

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

Alf P. Steinbach

* 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
 
E

Erik Wikström

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

Grizlyk

David said:
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
 

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

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,222
Latest member
patricajohnson51

Latest Threads

Top