Originally Posted by
deoren
Good catch, I *think* I meant to say: "B::foo() will not overload A::foo() because they're not from the same scope"
That *is* what you said. It is true in a sense, but it still misses the point that two functions with the same signature cannot meaningfully overload one another. They override one another.
Maybe you need to better understand the purpose in order to understand the rules and effects? The purpose of method overloading is to simplify a class interface such that you can have multiple methods with the same name (and presumably, a similar purpose) but different parameters. For example, it is common to overload constructors (in which case, the possibility of overloading the same "name" is essential). Let's say you have a class time, and you want to allow someone to instantiate a time object with either:
Code:
time::time (int hours, int minutes, int seconds);
//or
time::time (string when);
You might specify in the documentation that the string should be of the form HH::MM::SS. So the point here is that overloaded methods have different signatures. B::foo() and A::foo() do not.
How often is that approach used, and should any warning bells be going off when you find yourself using it? It's probably because I'm new, but it almost seems like a workaround for something else.
It kind of is a work-around for the aforementioned C++ mechanics, but there is nothing wrong with that; it's certainly much tidier than any alternative I can think of. If you have a base class with a set of overloaded methods, and you want to add another such method in a derived class, by default because of the scoping effects CornedBee etc described, the other base methods will be hidden. That is often not desirable -- you probably want the derived class to inherit the other methods as well. The "using" thing is a pretty simple solution to that.
Pay attention when overriding methods. If you don't use the exactly same parameters and return values, you'll end up with an overloaded method, and not an overridden one. Such mistakes are very hard to debug!
Overriding is often used to implement polymorphism, multiple classes derived from the same base, with the same interface, but slightly different behaviour. A classic example is class Animal, class Dog, and class Cat, all of which implement a method:
But when a cat speaks, it says meow. When a dog speaks, it says woof. If Animal::speak() for some reason is not virtual, and you define Dog::speak with a different signature, eg:
this could lead to confusion: people who are used to using the speak method in classes derived from Animal will do this:
And instead of a woof, they'll get the default animal sound. This example is contrived; probably the most common screw-up here is something like this:
Code:
Animal::whatever (int a, float b);
Dog::whatever (float b, int a);
Putting the arguments in the wrong order. Dog::whatever does not properly override Animal::whatever.