Why Should I Use the "Using" Keyword to Access My Base Class Method

Why should I use the using keyword to access my base class method?

The action declared in the derived class hides the action declared in the base class. If you use action on a Son object the compiler will search in the methods declared in Son, find one called action, and use that. It won't go on to search in the base class's methods, since it already found a matching name.

Then that method doesn't match the parameters of the call and you get an error.

See also the C++ FAQ for more explanations on this topic.

using keyword for base class variable

Generic programming is slightly different from object oriented programming.

Your mTuple is an example of a nondependent name. As far as the compiler is concerned, at the time the template definition is processed the compiler doesn't know that the class template has inherited a data member named mTuple. It might be obvious to you, but it is not obvious to the compiler. At this stage, the compiler is oblivious to the obvious.

If the methods of the derived class template wish to use some member of the parent class template, the compiler needs to be explicitly told to do so. Hence the using.

Edit

The above was a bit terse. It is important to remember that those class templates are not classes. They are templates that eventually define a class. Up until the moment that the class template is used to define a class that class template isn't quite real. More importantly, for a class template that inherits from some other class template, that inheritance isn't quite real. The compiler doesn't know about that inheritance unless it is explicitly told about it. That's why you will see derived class templates import the parent class's members via using ParentClass<Type>::member (for example).

Edit #2

Marshall Cline discusses this topic in his C++-FAQ at http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19

Edit #3

(Per request) Just because some code compiles on your compiler does not mean it compiles on every compiler (for the same language). Compiler vendors add their own 'features' to a language, sometimes very intentionally, sometimes just because the vendors themselves goofed up, and sometimes because the standard itself is buggy. This issue of not-quite-standard compilers has been a problem for a long time, with many languages. The problem apparently is quite rampant when it comes to generic programming.

You can do everything right (or so you think): Turn on all standard warnings and then some, run your code through some commercial code analyzer, and you still might not have portable code.

Why does calling a method in my derived class call the base class method?

There's a difference between new and virtual/override.

You can imagine, that a class, when instantiated, is nothing more than a table of pointers, pointing to the actual implementation of its methods. The following image should visualize this pretty well:

Illustration of method implementations

Now there are different ways, a method can be defined. Each behaves different when it is used with inheritance. The standard way always works like the image above illustrates. If you want to change this behavior, you can attach different keywords to your method.

1. Abstract classes

The first one is abstract. abstract methods simply point to nowhere:

Illustration of abstract classes

If your class contains abstract members, it also needs to be marked as abstract, otherwise the compiler will not compile your application. You cannot create instances of abstract classes, but you can inherit from them and create instances of your inherited classes and access them using the base class definition. In your example this would look like:

public abstract class Person
{
public abstract void ShowInfo();
}

public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}

public class Student : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a student!");
}
}

If called, the behavior of ShowInfo varies, based on the implementation:

Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'

person = new Student();
person.ShowInfo(); // Shows 'I am a student!'

Both, Students and Teachers are Persons, but they behave different when they are asked to prompt information about themselves. However, the way to ask them to prompt their information, is the same: Using the Person class interface.

So what happens behind the scenes, when you inherit from Person? When implementing ShowInfo, the pointer is not pointing to nowhere any longer, it now points to the actual implementation! When creating a Student instance, it points to Students ShowInfo:

Illustration of inherited methods

2. Virtual methods

The second way is to use virtual methods. The behavior is the same, except you are providing an optional default implementation in your base class. Classes with virtual members can be instanciated, however inherited classes can provide different implementations. Here's what your code should actually look like to work:

public class Person
{
public virtual void ShowInfo()
{
Console.WriteLine("I am a person!");
}
}

public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}

The key difference is, that the base member Person.ShowInfo isn't pointing to nowhere any longer. This is also the reason, why you can create instances of Person (and thus it does not need to be marked as abstract any longer):

Illustration of a virtual member inside a base class

You should notice, that this doesn't look different from the first image for now. This is because the virtual method is pointing to an implementation "the standard way". Using virtual, you can tell Persons, that they can (not must) provide a different implementation for ShowInfo. If you provide a different implementation (using override), like I did for the Teacher above, the image would look the same as for abstract. Imagine, we did not provide a custom implementation for Students:

public class Student : Person
{
}

The code would be called like this:

Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'

person = new Student();
person.ShowInfo(); // Shows 'I am a person!'

And the image for Student would look like this:

Illustration of the default implementation of a method, using virtual-keyword

3. The magic `new` keyword aka "Shadowing"

new is more a hack around this. You can provide methods in generalized classes, that have the same names as methods in the base class/interface. Both point to their own, custom implementation:

Illustration of the "way around" using the new-keyword

The implementation looks like the one, you provided. The behavior differs, based on the way you access the method:

Teacher teacher = new Teacher();
Person person = (Person)teacher;

teacher.ShowInfo(); // Prints 'I am a teacher!'
person.ShowInfo(); // Prints 'I am a person!'

This behavior can be wanted, but in your case it is misleading.

I hope this makes things clearer to understand for you!

What really is the purpose of base keyword in c#?

The base keyword is used to refer to the base class when chaining constructors or when you want to access a member (method, property, anything) in the base class that has been overridden or hidden in the current class. For example,

class A {
protected virtual void Foo() {
Console.WriteLine("I'm A");
}
}

class B : A {
protected override void Foo() {
Console.WriteLine("I'm B");
}

public void Bar() {
Foo();
base.Foo();
}
}

With these definitions,

new B().Bar();

would output

I'm B
I'm A

Should the base Keyword be used?

You should not use base unless you specifically mean "Even if there is a method in this class that overrides the base implementation, I want to call the base implementation and ignore the one on this class".

Using base bypasses the virtual dispatch mechanism that is so important in polymorphism by causing a call instruction to be emitted rather than callvirt.

So saying base.Foo() is very, very different in semantics to saying this.Foo(). And you almost always want the latter.

Should I use virtual, override, or both keywords?

When you override a function you don't technically need to write either virtual or override.

The original base class declaration needs the keyword virtual to mark it as virtual.

In the derived class the function is virtual by way of having the ¹same type as the base class function.

However, an override can help avoid bugs by producing a compilation error when the intended override isn't technically an override. For instance, the function type isn't exactly like the base class function. Or that a maintenance of the base class changes that function's type, e.g. adding a defaulted argument.

In the same way, a virtual keyword in the derived class can make such a bug more subtle by ensuring that the function is still virtual in the further derived classes.

So the general advice is,

  • Use virtual for the base class function declaration.

    This is technically necessary.

  • Use override (only) for a derived class' override.

    This helps maintenance.

Example:

struct Base { virtual void foo() {} };
struct Derived: Base { void foo() override {} };


Notes:
¹ C++ supports covariant raw pointer and raw reference results. With covariance the type of the override isn't exactly the same. It just has a compatible type.

C++ keyword using

See this
Why should I use the "using" keyword to access my base class method?

Also this

using

The using keyword is used to import a
namespace (or parts of a namespace)
into the current scope. Example code:
For example, the following code
imports the entire std namespace into
the current scope so that items within
that namespace can be used without a
preceeding “std::”.

using namespace std;

Alternatively, the next code snippet
just imports a single element of the
std namespace into the current
namespace:

using std::cout;

Related Topics: namespace

Using is for namespace specifications/use - not as I think you are trying to use it.



Related Topics



Leave a reply



Submit