This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Question about inheritance


Hi Peter, this type of questions are better sent to general
newsgroup about C++.  Or maybe you can read a good book about
C++ (see the FAQ about C++ for good references).

To make you not feel too bad about this, I answered your
question below this time.

Regards,

Carlo

| class foo
| {
| public:
| 	typedef int hi;
| 
| 	void doit (void)
| 	{
| 		if (sizeof(hi) == sizeof(int))
| 			puts("int");
| 		else
| 			puts("something else");
| 	}
| };
| 
| class stuff : public foo
| {
| public:
| 	typedef double hi;
| };
| 
| int
| main (void)
| {
| 	stuff s;
| 
| 	s.doit();	// Prints out "int", not "something else"
| 	return 0;
| }
| 
| ---
| 
| The function doit, thus, does not see the derived class' "hi", only the
| parent class.  I couldn't say if this is the correct behaviour, since I
| don't know C++ as well as most others, but a better question would be,
| how to get doit to somehow see the derived class "hi" instead of the
| parent class "hi"?
| 
| Thanks for any help you can provide.
| 	Peter

You can't inherit a typedef Peter.  When `doit' is compiled, it doesn't know
anything about class stuff, and the compiler will use foo::hi and replace
sizeof(hi) during compilation with the constant 4.

One way of doing this would be using a template, causing `doit' to be
compiled for every different type `hi' seperately (increasing the size
of your executable of course).

#include <iostream>

template <class B>
class doit_ct : public B {
public:
  void doit (void)
  {
    if (sizeof(hi) == sizeof(int))
      cout << "equals sizeof(int)" << endl;
    else
      cout << "something else" << endl;
  }
};

class int_hi {
public:
  typedef int hi;
};

class int_double {
public:
  typedef double hi;
};

typedef doit_ct<int_hi> foo;
class stuff : public doit_ct<int_double> {
public:
  // ...
};

int
main (void)
{
  stuff s;
  foo f;

  s.doit();
  f.doit();
  return 0;
}

gives the output:

~/tmp>a.out
something else
equals sizeof(int)

If you want to do this at runtime (and have no code bloat for
`doit') then you need to use `virtual' the way you did it:

#include <iostream>

class foo {
public:
  typedef int hi;

  void doit (void)
  {
    if (sizeof_hi() == sizeof(int))
      cout << "equals sizeof(int)" << endl;
    else
      cout << "something else" << endl;
  }

protected:
  virtual size_t sizeof_hi(void) { return sizeof(hi); }
};
 
class stuff : public foo {
public:
  typedef double hi;
protected:
  virtual size_t sizeof_hi(void) { return sizeof(hi); }
};
 
int
main (void)
{
  stuff s;
  foo f;

  s.doit();
  f.doit();
  return 0;
}

-- 
Carlo Wood  <carlo@runaway.xs4all.nl>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]