Class Inheritance Problem

Started by
7 comments, last by sooner123 11 years, 4 months ago
I'm trying to learn about class inheritance and the code below is a combination of my own attempt to understand it and some code from one of the tutorials I'm reading.

I have two questions:
1. Why is this printing out the wrong value for y?
2. Why does the initialization of testBaseClass need to be a pointer? In other words, why BaseClass* testBaseClass and not just BaseClass testBaseClass?


#include <iostream>
#include <stack>

using namespace std;

class BaseClass
{
public:
int x, y;
};

class DerivedClass: public BaseClass
{
public:
DerivedClass(int x, int y)
{
x = x;
y = y;
}
};

int main(int argc, char* argv[])
{
BaseClass* testBaseClass = new DerivedClass(3, 4);
cout << testBaseClass->y;
}
Advertisement

1. Why is this printing out the wrong value for y?

How do you expect the compiler to figure out what you mean by x and y, since your class fields have the same name as your constructor parameters? Change the name of either of those to differentiate them, otherwise it's not going to work.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

Hello

2. Why does the initialization of testBaseClass need to be a pointer? In other words, why BaseClass* testBaseClass and not just BaseClass testBaseClass?


I think you are mistaken. You can do this:
BaseClass testBaseClass = DerivedClass(3, 4);
This variable will be an automatic variable, meaning it is destroyed when you code goes outside the nearest brace "}" (out of scope).

In your example,
BaseClass* testBaseClass = new DerivedClass(3, 4);
The object is allocated at run-time by the "new" operator, and the object stays valid until you deallocate it with the "delete" operator.
Ok that fixed my first problem. I intentionally did it that way because I was told by someone that you could do constructor assignments this way and that it would assume the left side was the member and the right side was the parameter.

So I just have one more question.

I want to be able to make a class structure where the base class can have a method AddChild, and can add an arbitrary amount of instances of the derived class.

Basically something like:

base class = widget
derived class = dialogWidget
derived class = buttonWidget

and you create an instance of widget,
then you create an instance of dialogWidget,
then you create an instance of buttonWidget,
then somehow you "add" the dialogWidget instance to the widget instance.
and you then add the buttonWidget instance to the widget instance

Is there an established way of doing this? like a resizable array of widgets INSIDE the widget class declaration?
The exception being when using the initialization list (as you should if you mean "initialize" rather than "assign in the constructor").

This would be perfectly fine (though probably still confusing to some people)

DerivedClass(int x, int y) : x(x), y(y) {}


Well, actually it wouldn't be, because the compiler would then point out a severe flaw in your code. Why does the derived class have to initialize the base class? How is it a good idea to have instances of the base class being completely uninitialized? And if they aren't supposed to use/need x/y, why are they declared in the base class?


In BaseClass
BaseClass(int x, int y) : x(x), y(y) {}

In DerivedClass
DerivedClass(int x, int y) : BaseClass(x,y) {}


About 2): Because polymorphism only works with pointers/references. C++ is too low level to hide such details from you, so when you use actual instances, you're dictating the exact memory layout of the class in question. When using the base class, everything beyond what is part of the base class is cut off. Because it can be annoying to fiddle with pointers just for that, you might want to use smart pointers for that (though that still won't get you correct behavior when assigning/copying).
f@dzhttp://festini.device-zero.de

So I just have one more question.

I want to be able to make a class structure where the base class can have a method AddChild, and can add an arbitrary amount of instances of the derived class.

Basically something like:

base class = widget
derived class = dialogWidget
derived class = buttonWidget

and you create an instance of widget,
then you create an instance of dialogWidget,
then you create an instance of buttonWidget,
then somehow you "add" the dialogWidget instance to the widget instance.
and you then add the buttonWidget instance to the widget instance

Is there an established way of doing this? like a resizable array of widgets INSIDE the widget class declaration?


The C++ standard library is the established way of doing this (google for std::vector). Vectors are templated so that you can specify it to contain pointers to your base widget class and store the pointers in there (vectors are resizable arrays). So push the widget pointers passed into the AddChild function into the vector to have a collection of pointers to widgets.
This is the example code they gave in the problem that should work if I implement the class structure properly:


//create the main object
BaseClass* testParentClass = new UpperDerivedClass(3, 4);
//create child objects
BaseClass* testChildClass1 = new LowerDerivedClass("john", 1, 2);
BaseClass* testChildClass2 = new LowerDerivedClass("mark", 7, 5);
//add child objects
testParentClass->AddChild(testChildClass1);
testParentClass->AddChild(testChildClass2);
testParentClass->RemoveChild(testChildClass1);


And though I understand everything else, I have no idea how to approach this part. At first I thought you'd just have an array of type BaseClass within the definition of BaseClass, but the way the example code add's children isn't as if it's an array at all. It references the added children by name. I can't think of any way this could work.

At no point is anything referenced with an index. Not during the add or a remove. So isn't this something different from an array or vector?
The point is to show you that you can have a pointer to a BaseClass point to a Derived class. If it wasn't a pointer, you would literally have a BaseClass in Memory, and you can't turn the BaseClass you already have into a DerivedClass. The pointer, on the other hand, isn't in memory, and thus by using the new operator you're allocating memory for it to use. The BaseClass pointer can point to anything that's a BaseClass, so when you create a "new DerivedClass" you're allocating the memory that the BaseClass pointer points too.

The reason that you output TestBaseClass->y is to show that when you allocated memory for a DerivedClass on a BaseClass pointer, you used the DerivedClass constructor and not the BaseClass instructor, which becomes important later if you use virtual funtions.

Also, I believe linked lists are becoming relatively pointless with std::vectors and std::lists.

A std::vector, at first sight, seems like a resizable array, however it is much more than that. It has many funtions and operators that make it far more useful and versatile than an array. Unless I have to use an array, I generally use an std::vector instead.

std::list's are doubly-linked list. Unless you have special requirements for your linked list or need more than a doubly linked list (Which is very rare), this is literally the standard linked list, and unless it is a learning experience there is no point to program your own. (Programming your own linked list as a learning experience is very rewarding, however, and lets you understand the inner workings of linked lists / arrays / vectors far better).

I'm a game programmer and computer science ninja !

Here's my 2D RPG-Ish Platformer Programmed in Python + Pygame, with a Custom Level Editor and Rendering System!

Here's my Custom IDE / Debugger Programmed in Pure Python and Designed from the Ground Up for Programming Education!

Want to ask about Python, Flask, wxPython, Pygame, C++, HTML5, CSS3, Javascript, jQuery, C++, Vimscript, SFML 1.6 / 2.0, or anything else? Recruiting for a game development team and need a passionate programmer? Just want to talk about programming? Email me here:

hobohm.business@gmail.com

or Personal-Message me on here !

Thanks that was very informative. I feel like I'm learning a lot about coding just from this one exercise.

This topic is closed to new replies.

Advertisement