Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Derived Structure in Derived Class?? (http://www.velocityreviews.com/forums/t587588-derived-structure-in-derived-class.html)

David 01-27-2008 05:18 PM

Derived Structure in Derived Class??
 
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!!



Alf P. Steinbach 01-27-2008 05:47 PM

Re: Derived Structure in Derived Class??
 
* 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?

Erik Wikström 01-27-2008 06:13 PM

Re: Derived Structure in Derived Class??
 
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

Grizlyk 01-29-2008 07:38 AM

Re: Derived Structure in Derived Class??
 
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


All times are GMT. The time now is 08:06 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.