Inheritance question

K

keith

Forgive me if this an FAQ; I did look, but couldn't find it, so...

I know that if I declare a method virtual in the base class, then at
run time my derived class version will be called. How do I do
something sort of similar with a member variable?

What I mean is that I have a context struct in my base class, which a
(non-virtual) method twiddles with. What I would like is the overload
the context struct in the derived class, and have the base class
method twiddle with the derived class context struct.

If you see what I mean.

(I think you can guess I'm rather new to this C++ thingy!)
 
K

Kai-Uwe Bux

Forgive me if this an FAQ; I did look, but couldn't find it, so...

I know that if I declare a method virtual in the base class, then at
run time my derived class version will be called. How do I do
something sort of similar with a member variable?

Since you don't call member variables (unless they happen to be function
objects), it is somewhat hard to understand what you mean by "something
sort of similar".

What I mean is that I have a context struct in my base class, which a
(non-virtual) method twiddles with. What I would like is the overload
the context struct in the derived class, and have the base class
method twiddle with the derived class context struct.

If you see what I mean.

Not sure. Maybe you are thinking of something like this (uncompiled code,
may contain errors):


struct ContextBase {
// some data
};

struct ContextDerived : public ContextBase

struct Base {
private:

Base ( Base const & other );
Base& operator= ( Base const & rhs );

protected:

Base ( ContextBase* ptr )
: context_data_ptr ( ptr )
{}

public:

ContextBase* context_data_ptr;

Base ( void )
: contect_data_ptr ( new ContextBase )
{}

virtual
~Base ( void ) {
delete context_data_ptr;
}

void member_function ( void ) {
do_something( context_data_ptr );
}

};

struct Derived : public Base {

Derived ( void )
: Base ( new ContextDerived )
{}

};


However, to me the excessive use of pointers indicates that this might not
be a good design. What is the underlying problem that you are trying to
solve? It appears that you might be running into the dark corners of the
language because you are headed the wrong way.


Best

Kai-Uwe Bux
 
K

keith

However, to me the excessive use of pointers indicates that this might not
be a good design. What is the underlying problem that you are trying to
solve? It appears that you might be running into the dark corners of the
language because you are headed the wrong way.

I'm more than prepared to believe that I have made a basic design up-
****, and this group is the closest thing I have to a language mentor,
so please redirect my thinking if that is what's needed...

Let's see if I can put together a minimal example (this is pseudo-code
- untested):

class BASE
{
private:
struct base_ctx
{
...
} ctx_;

public:
void twiddle();
};

void BASE::twiddle()
{
memset(&ctx_, somevalue, sizeof(ctx)); // for example only
}

//--------------------------------

class DERIVED : public BASE
{
struct derived_ctx : base_ctx
{
... // additional contents, different size
} ctx_;
}

//--------------------------------

int main()
{
DERIVED Derived;

// What I want is for the following call to twiddle
// with the contents of the derived_ctx struct
// instead of the contents of the base_ctx struct
// without having to exactly duplicate the contents
// of the twiddle member function in the DERIVED
// class.

Derived.twiddle();
}
 
V

Victor Bazarov

I'm more than prepared to believe that I have made a basic design up-
****, and this group is the closest thing I have to a language mentor,
so please redirect my thinking if that is what's needed...

Let's see if I can put together a minimal example (this is pseudo-code
- untested):

class BASE
{
private:
struct base_ctx
{
...
} ctx_;

public:
void twiddle();
};

void BASE::twiddle()
{
memset(&ctx_, somevalue, sizeof(ctx)); // for example only
}

//--------------------------------

class DERIVED : public BASE
{
struct derived_ctx : base_ctx
{
... // additional contents, different size
} ctx_;
}

//--------------------------------

int main()
{
DERIVED Derived;

// What I want is for the following call to twiddle
// with the contents of the derived_ctx struct
// instead of the contents of the base_ctx struct
// without having to exactly duplicate the contents
// of the twiddle member function in the DERIVED
// class.

Derived.twiddle();
}

Are you looking for polymorphic behaviour without the use of any
polymorphic constructs (like virtual functions)? The main problem
is that your 'twiddle' function does not know that it's called
for a 'DERIVED' object. It can only know that it's called for
an object of type 'BASE', but to learn whether it's a stand-alone
object or a subobject of something else is beyond its abilities.

I can only imagine the use of templates in this case, and then still
you need to pass the object itself to the function:

#include <iostream>

struct Base {
struct Base_inner {
void foo() { std::cout << "Base_inner\n"; }
} inner;

template<class T> static void twiddle(T &t) {
t.inner.foo();
}
};

struct Derived : Base {
struct Derived_inner : Base_inner {
void foo() { std::cout << "Derived_inner\n"; }
} inner;
};

int main() {
Derived d;
d.twiddle(d); // see how 'd' needs to have 'd' passed to it?
}

There is no way in C++ to make *data* virtual. Only functions (i.e.
the behaviour) can be virtual.

V
 
J

John Harrison

Forgive me if this an FAQ; I did look, but couldn't find it, so...

I know that if I declare a method virtual in the base class, then at
run time my derived class version will be called. How do I do
something sort of similar with a member variable?

What I mean is that I have a context struct in my base class, which a
(non-virtual) method twiddles with. What I would like is the overload
the context struct in the derived class, and have the base class
method twiddle with the derived class context struct.

If you see what I mean.

(I think you can guess I'm rather new to this C++ thingy!)

I would suggest you write a virtual function 'get_thing_to_twiddle_with'
that returns the address of the twiddlee, then the base class can
twiddle away to it's hearts content.

john
 

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
474,291
Messages
2,571,493
Members
48,164
Latest member
KerrieWind

Latest Threads

Top