I want to call a derived class function that isn't defined in the base class using base class pointers. but this always raises the error:
error C2039: ‘derivedFunctionName’ : is not a member of ‘BaseClass’
Do you know how I could get around this?
Thanks,
You can't call a member that appears only in a derived class through a pointer to the base class; you have to cast it (probably using dynamic_cast) to a pointer to the derived type, first -- otherwise the compiler has no idea the method even exists.
It might look something like this:
void someMethod(Base* bp) {
Derived *dp = dynamic_cast<Derived*>(bp);
if (dp != null)
dp->methodInDerivedClass();
}
One way is to make the function virtual in the base class and then override it in the derived class. You don't have to define the function in the base class (although you can), but you can use the pure virtual syntax in the base class virtual void foo() = 0; if you don't want to provide an implementation in the base class.
This will let you override it in the derived class and still call it in the base class through a base class pointer. This is known as 'polymorphism'.
You can also just cast it to a derived type at run time if you are sure it is actually a derived class pointer at that time. If it is not, it will crash.
You can call a derived class member through a pointer to a base class as long as the method is virtual. That's what polymorphism is about.
In order for that to work you must declare a virtual method (probably pure virtual) in the base class and overload it in the derived class.
Note that you will run into issues calling the derived member from the base method. Do some ARM or Meyers reading if this doesn't make sense to you.
Related
I want to call a derived class function that isn't defined in the base class using base class pointers. but this always raises the error:
error C2039: ‘derivedFunctionName’ : is not a member of ‘BaseClass’
Do you know how I could get around this?
Thanks,
You can't call a member that appears only in a derived class through a pointer to the base class; you have to cast it (probably using dynamic_cast) to a pointer to the derived type, first -- otherwise the compiler has no idea the method even exists.
It might look something like this:
void someMethod(Base* bp) {
Derived *dp = dynamic_cast<Derived*>(bp);
if (dp != null)
dp->methodInDerivedClass();
}
One way is to make the function virtual in the base class and then override it in the derived class. You don't have to define the function in the base class (although you can), but you can use the pure virtual syntax in the base class virtual void foo() = 0; if you don't want to provide an implementation in the base class.
This will let you override it in the derived class and still call it in the base class through a base class pointer. This is known as 'polymorphism'.
You can also just cast it to a derived type at run time if you are sure it is actually a derived class pointer at that time. If it is not, it will crash.
You can call a derived class member through a pointer to a base class as long as the method is virtual. That's what polymorphism is about.
In order for that to work you must declare a virtual method (probably pure virtual) in the base class and overload it in the derived class.
Note that you will run into issues calling the derived member from the base method. Do some ARM or Meyers reading if this doesn't make sense to you.
Note: I am not asking why a parent class need to have virtual method.
I remember something coding guideline like that(I don't remember well and just try to express as my own word,hope I have correct wording): if the parent class have virtual method,the derived class should also at least have one virtual method, even the derived class would not have derived class from itself, if the derived class really no need to have any virtual method, set destructor as virtual. The reason behind it is something like "prevent duplicate virtual table", what is it talking about?
And I also remember a related example like that:
class A{
virtual f();
};
class B : public A{
};
B as no derived class, if B has no virtual method, the consequence is something like "any place that include B will have a duplicate virtual table generated by compiler" (also is just expressed from my impression), what is the meaning of that (if it is true)?
Note the following:
If the base class has a virtual member function other than a destructor, the derived class inherits that function.
If the base class declares a member function as virtual, and the derived class declares a member function of the same name with the same argument types, then the derived class function is automatically virtual, and overrides the base class's function.
If the base class has a virtual destructor, the derived class's destructor is automatically virtual, whether user-declared or not, and overrides the base class's destructor.
The example you gave is not in any way problematic. I would advise you to forget everything you think you remember about this coding standard.
class base
{
public:
virtual void showbase() {
// ----------
}
};
class base1 {
public:
virtual void showbase1() {
// -------
}
};
class derived : public base, public base1
{
void showbase() {
// ----
}
void showbase1() {
// -------
}
};
int main()
{
base* p = new derived();
p->showbase1();
base1* p1 = new derived();
p1->showbase();
}
As per my understanding about virtual function is that compiler deals it with run time (vtable mechanism), then why I am getting compile time error.
To simulate a compiler, consider what a compiler sees:
class base
{
public:
virtual void showbase() {
// ----------
}
};
base* p = /*blah blah*/;
p->showbase1();
Yes, base is a polymorphic class. And p is indeed a pointer-tobase. But since p points just to a base, and importantly not to a base1 (where showbase1 lives) the compiler interprets the above code like this. Obviously, I'm paraphrasing:
Here is a class named `base` with a single virtual method called `showbase`.
Here is a pointer to a `base` object. Call the method named `showbase1`
And the compiler complains:
Um, excuse me buddy, but base doesn't have a method called
showbase1.
You asked:
[My] understanding about virtual function is that compiler deals with
it at run time. Why I am getting compile time error?
Because the code you've written is nonsense. Here basically is how polymorphism works.
You define a base class with virtual methods.
You define a derived class that overrides those virtual methods.
The compiler creates a vtable which maps the names of the methods in the base class to the implementation in the derived class.
When you call a method in the base class through a pointer (or ref) to the base class, the derived class' implementation is called.
But what you are trying to do is:
Define a base class with virtual methods.
Define a derived class which overrides those virtual methods.
Call a function in a completely different class.
As per my understanding about virtual function is that compiler deals it with run time (vtable mechanism), then why I am getting compile time error.
"Deals with it" is pretty vague and vtables are not magic; In C++ virtual dispatch allows for the actual function called to be one that overrides the statically declared virtual function. That means that the function which is being overridden must be known at compile time.
The vtable does not contain information that would be necessary to look up functions at run-time. Instead, it's basically just a list of pointers to overriding functions. The base provides a complete list of its virtual functions and so, given a particular base type, the compiler knows at compile-time where to go in the vtable for that base for a particular function override; The compiler can generate code that goes directly to that spot in the vtable, gets the pointer, and calls the overriding function.
Then, at run-time, when the actual object of derived type is created, the derived object's constructor fills in the base's vtable, so that anything checking the vtable will get pointers to the derived type's functions.
So the problem with your code is that the function you're calling, showbase(), is not on the list of virtual functions for the type the compiler knows you're accessing, base1; The compiler can't know where in base1's vtable to get a pointer for a function override named showbase(), because there is no such entry in base1's vtable.
A base class pointer to a derived class can only access the member functions defined in the base class. It is illegal to try and access other functions defined in the derived class through it. In your case base class does not define showbase1 and therefore this is illegal
base* p = new derived();
p->showbase1(); //illegal
However, you can do this:
p->showbase(); // legal because showbase is a member function of base
Similarly you can't access showbase1 using a base class pointer
base1* p1 = new derived();
p1->showbase(); //illegal
p1->showbase1(); //legal
Your base class(es) only know about their own member functions, so you can't use it this way. You could do this instead:
base* p = new derived();
p->showbase();
base1* p1 = new derived();
p1->showbase1();
To answer your question about runtime polymorphism, it is dealing with runtime polymorphism (late binding) via the vtable, as you say. But with multiple inheritance, there is essentially a vtable for for each base class. You can't access one base class' vtable via a pointer to the other base class.
p'static type s type is base and hence you can only call with it functions that have been definied into base even if at the end, it will be the functions from derived which will be called because p's dynamic type is derived
Same thing happens for p1.
Maybe you meant p->showbase(); and p1->showbase1();
I am trying to inherit a class defined in a public library while overriding some of its functions and member types and I have a few questions:
None of the functions are declared as virtual in the super class so is it still ok to override these functions?
Can I override member variables by simply declaring a variable with the same name but a different type. Is this the same as hiding?
Also, if 2 is possible, then can I do the following:
public class A {
public:
class Member {
Member (//some params) {};
}
}
class B : public A {
public:
class Member : public A::Member {
Member () :
A::Member(//some params)
{
// Some additions to B::Member
}
}
}
Note: Since I cannot change the superclass templating is out of the question.
If you hide the base class's functions - you can't override them as they're not virtual - you have to keep in mind that certain scenarios like calling via pointer or reference to the base class will not work as expected and might yield "interesting" results. You'll also run into issues if the destructor is non-virtual and you're trying to destroy the derived object via a pointer to base class.
You'd be hiding the base class's member of the same name, but again it is very likely that it will not do what you expect. The base class implementation will still reference the base class's member, while the derived class's implementation will reference the derived class's member.
No.
You might want to look into wrapping the "base" class instead of trying to derive from it.
you override virtual functions. if it is not, you are hiding.
it is name hiding.
no you can not.
No, you can't override them. It will be simply hiding them.
It's not overriding, it is hiding.
You can't.
What other reason apart from inheritance should a class need to have its functions as virtual?
What happens during run time where a base class is inherited and the derived class doesn't implement few of the base class function and a third class calls that undefined methods which are defined as virtual in base. seg fault or will it call the base class function?
What should I do if I don't want to define all the functions in my base class on my derived class but still have the necessary inheritance in place?
What other reason apart from inheritance should a class need to have
its functions as virtual?
There is no reasonable usage for having a virtual function, if you are not dealing with inheritance. Both are meant for each other.
What happens during run time where a base class is inherited and the
derived class doesn't implement few of the base class function and a
third class calls that undefined methods which are defined as virtual
in base. seg fault or will it call the base class function?
If Derived class don't make any declaration about the virtual function at all in its body, then (immediate) base class virtual functions are called with derived class object. On the other hand, if you simply declare virtual function in derived class but do not define it then it's a linker error. No segmentation fault.
What should I do if I don't want to define all the functions in my
base class on my derived class but still have the necessary
inheritance in place?
Though this is unclear, I would say, you simply don't declare/define virtual function (which you don't want) in derived class. It will use base class virtual functions.
If you do not reimplement a virtual method, a caller will call the base class one. This is sort of the point of using inheritance, IMO.
If you do not want a base class to implement a virtual method, you can declare it like this:
class Demo {
void foo() = 0;
};
This is what is called an abstract class. Note that you cannot create an instance of such a class. Any class which inherits from Demo must implement foo(), or it will also be an abstract class, and as such not instansiable.