Virtual functions: how to call the proper function?

Let's say I've defined in my interface,

1
2
3
4
5
//interface
class iClass {
     public:
     virtual void display(std::ostream&) const = 0;
};


And I have a class that derived from it,

1
2
3
4
5
//abstract class
class Class : public iClass {
	public:
		void display(std::ostream&) const;
	};


And I have two other classes deriving from Class

1
2
3
4
5
6
7
8
9
10
11
//concrete class
ClassA : Class {
     public:
     void display(std::ostream&) const;
};

//concrete class
ClassB : Class {
     public:
     void display(std::ostream&) const;
};


Say my main is,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void display(const char* aPointer, iClass* const arr[], int n) {
     //some stuff
     arr[i]->display(cout);
}

int main () {
	// Create Accounts for Angelina
	iClass* Angelina[2];
    
	// initialize Angelina's Accounts
	Angelina[0] = CreateAccount("Savings", 400.0); 
	Angelina[1] = CreateAccount("Chequing", 400.0);
	display("Angelina", Angelina, 2);
                           .  .  .
}


I also have an allocator,

1
2
3
4
5
6
7
8
9
10
	iClass* CreateAccount(const char* type, double amount) {
		iClass* a = nullptr;
		if ('S' == toupper(type[0])) {
			a = new ClassA(amount);
		}
		else if ('C' == toupper(type[0])) {
			a = new ClassB(amount);
		}
		return a;
	}


In my main, how do I call the appropriate display function? My program keeps executing the void Class::display(std::ostream&) function from my abstract class 'Class', but I want it to call the corresponding void display(std::ostream&) function from whichever class that the object was created.
So, if a = new ClassB(amount); was executed, I want it to run void ClassB::display(std::ostream&)

As it is now, no matter what I do, no matter what type of object was created (ClassA or ClassB), it always calls the display function from Class
Last edited on
If you want dynamic dispatch, you must use the virtual keyword:

1
2
3
4
class Class : public iClass {
	public:
		virtual void display(std::ostream&) const;
};


Here's a complete example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# include <iostream>

struct IBase {
    virtual std::ostream& display(std::ostream&) const = 0;
};

struct Base: IBase {
    virtual std::ostream& display(std::ostream& s) const override
    { return s << "Class::display()\n"; }
};
	
struct A: Base {
    std::ostream& display(std::ostream& s) const override
    { return s << "ClassA::display()\n"; }
};
struct B: Base {
    std::ostream& display(std::ostream& s) const override 
    { return s << "ClassB::display()\n"; };
};

int main() { 
    A my_a;
    B my_b;
    IBase &a = my_a, &b = my_b;
    a.display(std::cout); b.display(std::cout);
}


Live demo:
http://coliru.stacked-crooked.com/a/45b08066b09fe7e1
Last edited on
Always missing something so elementary, thank you.

I was under the impression that virtual keyword of a function should only be in the interface class; putting it elsewhere would be for only documentation purposes. Guess not.

Thanks again!
Registered users can post here. Sign in or register to post.