Today I was taught about virtual methods but got lost somewhere in the pointers.
Here is an example

class Person
{

protected:

string name;

public:

virtual string get_name()
{
return name;
}

};

class TFaculty:public Person
{
private: 
string title;

public:
virtual string get_name()
{
return title + " " + Person::get_name();
}

};
int main()
{

Person *arr[2]=
{ new TFaculty("Jane Doe", "Dr."),
  new TFaculty("John Doe","Mr.")

}  


return 0;
}

My code might be incomplete as I can't remember all of it.

What I'm confused about is that I have a two element array pointing to class Person which each element makes a new TFaculty object. I'm confused on how we are able to create an object of TFaculty if we are pointing to Person?

I know i'm seeing things wrong I hope someone can show me what is really going on.
The way i see it is like this:

int *ptr;
ptr=new double

I know this is not possible. So how is it that we can create a different datatype TFaculty when it's pointing to Person?

Please help me understand thanks.

Edited 5 Years Ago by ninjatalon: n/a

Because TFaculty inherits from Person. You can consider it a typeof Person and a typeof TFaculty so we can use pointers of either type to reference it. Do to the 'magic' of virtual methods the system knows that even though we are using a Person pointer we are really pointing at a TFaculty and it will call the correct method.

I was reading some of it up. So Person is only pointing to the base class of the TFaculty object. That's why we need virtual functions to be able to access the TFaculty get_name(). I get that. I guess what confuses me is where or what variable is both TFaculty object being saved at.

I understand if it would be like this.

TFaculty temp;

Person *x=&temp;

As I know that temp is a variable being placed in memory. And x is pointing only to the Base Class of temp.

But

Person *arr[2]=
{ new TFaculty("Jane Doe", "Dr."),
  new TFaculty("John Doe","Mr.")

}

I don't know what variable or how the TFaculty objects are being placed into memory.

Edited 5 Years Ago by ninjatalon: n/a

Your phrasing "I don't know what variable or how the TFaculty objects are being placed into memory" makes it sound to me like what's confusing you is actually the dynamic allocation (the "new" operator), not the virtual functions and polymorphism.

When a program is running, it accesses two (2) different sections of your computer's memory, the stack and the heap. The stack is the memory used by local variables and functions. When you are first starting to learn programming, this is where all of your variables get stored because of what you are taught about declaring variables and function arguments/parameters. In general, when you declare a variable inside a function, that variable gets placed on the stack. When the function ends the variable goes out of scope. When it goes out of scope, it is destroyed and removed from the stack. Observe:

void someFunction(int);

int main() {
  int myInt;            //declares a variable that is local to main()
                        //this variable gets stored on "the stack"
  someFunction(myInt);  //call someFunction()

  return 0;
}

void someFunction(int valueIn) {  //valueIn is stored on the stack and is a copy of myInt
  double myDouble;      //another variable on the stack

  //...

}                       //someFunction ends, since valueIn and myDouble are on the
                        //stack, they are no out of scope and get destroyed

The heap is really only used when your programs start using dynamic memory.
Have a look at this:

void someFunction(int *);

int main() {
  int* ptrInt = 0;      //declare a NULL pointer that is local to main()
                        //this pointer gets stored on "the stack", because it's locally scoped
  someFunction(ptrInt); //call someFunction()

  //at this point, ptrInt is no longer NULL, it points to an address on the heap that stores the anonymous int
  //that was allocated in someFunction()

  std::cout << *ptrInt << std::endl;

  delete ptrInt;        //de-allocate ptrInt to prevent a "memory leak"

  return 0;
}

void someFunction(int *pIntIn) {  //pIntIn is a pointer version of a "reference parameter"
  pIntIn = new int(10); //dynamically allocate an anonymous int on the heap

  //...

}                       //someFunction ends, since pIntIn is on the stack, it is now out of scope and gets destroyed
                        //but the anonymous int doesn't have a scope, so it still exists on the heap

In this version of the code, you are declaring a pointer to an int and assigning the memory address of an anonymous integer to it. There is a "blob" of memory out there (on the heap instead of the stack) that is ready to store an int value. To be able to access this memory and use it, you need to know the address of it. The int* "ptrInt" is a pointer, so you store the memory address in the pointer. You can then access this "blob" of memory through the pointer. There is no local variable that stores the int, its anonymous; you only know its address and you access it through that.

With your classes, it's the same type of thing. Because of the inheritance, a "TFaculty" is a type of "Person", which makes it legal for a Person* to point to a TFaculty. This is legal because a TFaculty object has a Person object hidden inside of it and the pointer points to the hidden Person object. This would not be legal if TFaculty did not inherit from Person. When you say:

Person *arr[2]=
{ new TFaculty("Jane Doe", "Dr."),
  new TFaculty("John Doe","Mr.")

}

You are saying that you want two (2) pointers to a Person (known as arr[0] and arr[1]). You then allocate 2 anonymous TFaculty objects (holding the specified data) on the heap and store their memory addresses in their respective pointers.

Edited 5 Years Ago by Fbody: n/a

I understand that because arr[2] is pointing to Person so when dealing with arr[0] and arr[1] we are only able to access the person object made inside the TFaculty object.

But what i don't understand is how can we allocate size of TFaculty Object inside a allocated space of size of Person.

When we point to an integer (int * ptr) it allocates 4 bytes somewhere in memory for the integer.

On the other hand I'm mostly likely wrong because we can run this (ptr=new int[4]) which creates 4 integers in that memory space.

Sounds like I'm not understanding New method. Does the New method resizes the memory space used. If so that makes sense to me.


Edit: Read on a tutorial I might understand it now.

When we declare int *ptr. It doesn't reserve any memory until we use the new operator. So when I call for new TFaculty for both arr[0] and arr[1] , it is at that point where memory is allocated for them. And because we are pointing to Person, We are only able to access the Person object of the TFaculty unless we use virtual methods. Can someone let me know if I'm correct so I can mark this as solved.

Edited 5 Years Ago by ninjatalon: n/a

I think you have the idea...

When you declare a pointer, enough memory is allocated on the stack to hold the pointer. The size of a pointer is normally either 4-Bytes or 8-Bytes depending on whether you're running 32-bits or 64-bits.

When you declare a 2-element array of Person*, the compiler reserves (2 x pointerSize)-Bytes on the stack (on a 32-bit system it would be 2x4, or 8, Bytes). Then, when you perform the actual allocation using new, an additional chunk of memory (objectSize)-Bytes long is allocated on the heap and the address of the first byte is returned for storage in the pointer. If your TFaculty type is 8-Bytes long, 8-Bytes are allocated, then the address of Byte 0 is stored in the pointer. Your TFaculty objects aren't actually stored in the array so no resizing is needed.

Edited 5 Years Ago by Fbody: n/a

This question has already been answered. Start a new discussion instead.