Archived

This topic is now archived and is closed to further replies.

Two C++ questions

This topic is 5373 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

1. Why can''t member variables of a derived class override member variables from the base class that have a greater type in the inheritence tree? By that I mean... you have a class B (inherits from class A) with member variable of type Y (inherits from class X) and a member variable of type X in class A. Now, if you want to add some greater functionality to the class why can''t you call the variable of type Y the same name as X and have it override it? Be useful, don''t you think? 2. Why can''t constructors be inherited directly??? I''m always forced to do this:

class B
{
    B::B() : A()
    {}
};
 

Share this post


Link to post
Share on other sites
You can accomplish that by having a member variable of type *X instead of just X. Then polymorphism allows you to put something of type Y or any other derived type in there.

They don't inherit them automatically because not everyone necessarily wants them.

Also in the case you posted above a default constructor will be created automatically by the compiler even if you don't declare one, and invoking it will automatically invoke the super class default constructor as well. So the code you posted does nothing the compiler can't do for you. If you have a more concrete example please post it.

[edited by - Dobbs on March 26, 2003 2:36:12 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Dobbs
You can accomplish that by having a member variable of type *X instead of just X. Then polymorphism allows you to put something of type Y or any other derived type in there.



Yes but it will only allow you to access the methods found in the base class, right?

quote:

They don''t inherit them automatically because not everyone necessarily wants them.



But why are constructors different? Why are any methods inherited directly then?

I''m at work so I can''t test my example or find a better example.... I''ll post again when I get home

Share this post


Link to post
Share on other sites
quote:
Original post by neXius
But why are constructors different? Why are any methods inherited directly then?

Because inheriting a ctor or dtor directly is wrong.


  
class base
{
base() {} //calls s.string()

virtual ~base() {} //calls s.~string()

string s;
};

class derived
{
//inherit ctor: whoops, doesn''t call t::string()

//inherit dtor: whoops, doesn''t call t::~string()

string t;
};

Share this post


Link to post
Share on other sites
quote:
Original post by sjelkjd

Because inheriting a ctor or dtor directly is wrong.




Inheriting destructors? That's different, since the base destructors are always called as well as the derived one...

In your example of course you would need to extend the constructor and destructor but this is not always the case...

So why is it wrong??


[edited by - nexius on March 26, 2003 8:39:14 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
hi,

Original post by Dobbs
You can accomplish that by having a member variable of type *X instead of just X. Then polymorphism allows you to put something of type Y or any other derived type in there.



Yes but it will only allow you to access the methods found in the base class, right?


True which is why pure virtual functions exist (I think)

I''m not sure but I think dynamic_cast<>() can overcome this.


PS: My C++ is not great so if anyone knows for sure then post the answer ''cos I''d be interested to know as well.



Share this post


Link to post
Share on other sites
quote:
Original post by neXius Inheriting destructors? That''s different, since the base destructors are always called as well as the derived one...


Surprise, surprise, the same thing happens with the ctr.

Share this post


Link to post
Share on other sites
quote:
Original post by sjelkjd

Surprise, surprise, the same thing happens with the ctr.




You''re right... But you still have to write:

B::B()
{}

In order for it to compile. So my question remains: Why can''t constructors be inherited directly?

After some testing I discovered that destructors are directly inherited, and so the base class destructor is ALWAYS executed no matter what. But not constructors...

And I think you''re right AP, I could just cast it to the derived class every time I wanted to use it, but I could never have (var->doDerivedStuff()) without typing (((Y*)var)->doDerivedStuff())

I don''t think so anyway

Share this post


Link to post
Share on other sites
I'm not really sure what you're talking about neXius when you say
quote:
After some testing I discovered that destructors are directly inherited, and so the base class destructor is ALWAYS executed no matter what. But not constructors...


What testing led you to this conclusion?

I'm not sure you really understand the terms you are using either. When a class inherits from another class it has all the member functions and variables that the base class has.


      
class base {
int size_;
double speed_;
public:
base(int size, double speed) {
size_ = size;
speed_ = speed;
}
}

class derived : public base {
derived()
...

Class derived is built on top of class base which therefore needs to be made first. When you call the derived constructor using new derived() it will first create the base class and then perform the rest of the derived class constructor. So what happens in this example? derived() gets called and the first thing that happens is the base class constructor gets called. Now the base class doesn't have a default constructor - it expects an integer and a double to be passed to it. Where is it going to get those from?

[edited by - petewood on March 27, 2003 4:51:58 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by petewood
I'm not really sure what you're talking about neXius when you say "After some testing I discovered that destructors are directly inherited, and so the base class destructor is ALWAYS executed no matter what. But not constructors... "

What testing led you to this conclusion?




Looking at it now, I'm not sure either. I guess I was just really confused.

Sorry about that. There's just one last hole in my understanding. Why can't you, going off your example, write the statement:

derived d = new derived(1, 4.0);

?

Edit: messed up the quote

[edited by - nexius on March 27, 2003 12:44:33 PM]

[edited by - nexius on March 27, 2003 12:45:11 PM]

Share this post


Link to post
Share on other sites
Okay, the answer to my question is you have to tell the base class what values to put into the constructor.

  
class derived : public base {
derived() : base(1, 4.0) {
}
}


you can''t do what you suggest because derived doesn''t have a constructor of type derived(int, double) . If you made one that would be another situation entirely!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:

1. Why can''t member variables of a derived class override member variables from the base class that have a greater type in the inheritence tree?



Why would you want to? It is not very safe. Besides, you can use union you know. It is all about planning.

quote:

2. Why can''t constructors be inherited directly??? I''m always forced to do this:



class B
{
B::B() : A()
{}
};




Constructors are for setting things up when creating the class. If you could inherit that then you basically would mess everything up faster than you can say Slartibartfast. That is automatically called when the class is created. Having two initializers would confuse the program.

Share this post


Link to post
Share on other sites
neXius if you have a *X member variable and put a derived *Y in it then yes you can only get at the member variables and functions declared in class X. If you design your class hierarchy well you should be able to get away with that and still get the desired behaviour just by overriding virtual functions. Another way as someone mentioned is to use runtime casting and type checking but more often than not that''s a workaround for a bad design.

Also you keep using examples like this:


class A {
public:
A() {};
};
class B : public A {
public:
B() : A() {};
};


I realize these are just dummied up examples, but do you realize that this code accomplishes the exact same thing:


class A {};
class B : public A {};


This is for a couple reasons. If you don''t declare a default constructor for A or B the compiler creates one for you. Also, when you construct a derived class it first constructs all the bases classes with their default constructors. So in some specific cases you do in a sense inherit constructors, but it isn''t done in general.

As for why constructors aren''t inherited in general: I can''t give you very concrete reasons but in my experience derived classes are designed in such a way that it really makes no sense to inherit constructors. The derived class often needs additional information or needs additional functionality for its constructor that simply isn''t provided by the base class. That''s why you''re creating a derived class, to have that extra functionality.

Share this post


Link to post
Share on other sites