I have the header file "testcode.h"
#ifndef TESTCODE_H
#define TESTCODE_H
class A
{
public:
A();
~A();
virtual void Foo();
public:
int mPublic;
protected:
int mProtected;
private:
int mPrivate;
};
class B : public A
{
public:
B();
~B();
void Foo();
};
#endif // TESTCODE_H
and a source file
#include "TestCode.h"
int main(int argc, char* argv[])
{
A* b = new B();
b->Foo();
b->mPublic = 0;
b->mProtected = 0;
b->mPrivate = 0;
delete b;
return 0;
}
Here, i would like to know that when I am calling "b->Foo", the Foo function of the class B is called instead of class A. However, the Foo function of class B is not declared as virtual. Can anyone elaborate on this ??
Once a function is declared virtual in a base class, it doesn't matter if the virtual keyword is used in the derived class's function. It will always be virtual in derived classes (whether or not it is so declared).
From the C++11 standard, 10.3.2:
If a virtual member function vf is declared in a class Base and in a
class Derived, derived directly or indirectly from Base, a member
function vf with the same name, parameter-type-list (8.3.5),
cv-qualification, and refqualifier (or absence of same) as Base::vf is
declared, then Derived::vf is also virtual (whether or not it is so
declared) and it overrides Base::vf. ...
B::Foo doesn't need to be declared as virtual--the fact that A::Foo is virtual and B derives from A means it's virtual (and overridden). Check out the msdn article on the virtual functions for more info.
Related
I have a class A that was inherited from class B. So the interface of class A contains some pure virtual functions of class B and some functions of class A. Now I need to make unit tests for class A, so wanna have some interface for class A that I can mock.
So now I'm wondering if the given code is correct in C++14 and can it lead to UB:
class Base1 {
public:
virtual void func() = 0;
};
class Base2 {
public:
virtual void func() = 0;
};
class Derived : public Base1, public Base2 {
public:
void func() override { }
};
int main() {
Derived d;
d.func();
return 0;
}
Yes, this code is well-formed and void func() overrides both A::func() and B::func(). From the C++14 standard:
[class.virtual]
If a virtual member function vf is declared in a
class Base and in a class Derived, derived directly or indirectly
from Base, a member function vf with the same name,
parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (or
absence of same) as Base::vf is declared, then Derived::vf is also
virtual (whether or not it is so declared) and it overrides
Base::vf.
I got surprised that a public(or private) virtual function can be overridden by a private(or public) virtual function. See below,
class C{
public:
virtual void f(){cout<<"C"<<endl;}
void g(){f();}
};
class D:public C{
private:
virtual void f(){cout<<"D"<<endl;}
};
int main(){
C * c = new D;
c->g();
return 0;
}
the code outputs D. I thought virtual function can only be overridden in the derived class with the same access specifier as in the base class, but this is apparently not how the above code works, am I observing something wrong? Why the access specifiers (public, protected and private) don't put restrictions on how the virtual function is overridden?
The C++11 Standard does not mention anything about the access specifiers of virtual functions in 10.3 Virtual Functions, at least I cannot find any.
Given that, D::f() is not directly accessible through an object or pointer of type D.
D* dPtr = new D;
dPtr->f(); // Does not work.
The following works:
C* cPtr = new D;
cPtr->f();
since C::f() is a public member function of C.
Update
Upon further investigation, I found the following:
11.5 Access to virtual functions
1 The access rules (Clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it. [ Example:
class B {
public:
virtual int f();
};
class D : public B {
private:
int f();
};
void f() {
D d;
B* pb = &d;
D* pd = &d;
pb->f(); // OK: B::f() is public,
// D::f() is invoked
pd->f(); // error: D::f() is private
}
— end example ]
using namespace std;
class Foo
{
public:
virtual void foo();
void foo2();
};
class Bar : public Foo
{
public:
void foo();
void foo2();
};
int main()
{
Foo* f = new Foo;
f->foo(); **//1**
f->foo2(); **//2**
return 0;
}
How compiler knows, 1) is dynamic in nature and 2) is static.
How both are internally called.
Collected from here . . .
Non-virtual member functions are resolved statically. That is, the member function is selected statically (at compile-time) based on the type of the pointer (or reference) to the object.
In contrast, virtual member functions are resolved dynamically (at run-time). That is, the member function is selected dynamically (at run-time) based on the type of the object, not the type of the pointer/reference to that object. This is called “dynamic binding.” Most compilers use some variant of the following technique: if the object has one or more virtual functions, the compiler puts a hidden pointer in the object called a “virtual-pointer” or “v-pointer.” This v-pointer points to a global table called the “virtual-table” or “v-table.”
A pure virtual function is a function that must be overridden in a derived class and need not be defined. A virtual function is declared to be “pure” using the curious =0 syntax. For example:
class Base {
public:
void f1(); // not virtual
virtual void f2(); // virtual, not pure
virtual void f3() = 0; // pure virtual
};
Base b; // error: pure virtual f3 not overridden
Here, Base is an abstract class (because it has a pure virtual function), so no objects of class Base can be directly created: Base is (explicitly) meant to be a base class. For example:
class Derived : public Base {
// no f1: fine
// no f2: fine, we inherit Base::f2
void f3();
};
Derived d; // ok: Derived::f3 overrides Base::f3
Example for Virtual or non-Virtual Fenction
#include <iostream>
using namespace std;
class Base {
public:
virtual void NameOf(); // Virtual function.
void InvokingClass(); // Nonvirtual function.
};
// Implement the two functions.
void Base::NameOf() {
cout << "Base::NameOf\n";
}
void Base::InvokingClass() {
cout << "Invoked by Base\n";
}
class Derived : public Base {
public:
void NameOf(); // *Virtual function*.
void InvokingClass(); // *Nonvirtual function.*
};
// Implement the two functions.
void Derived::NameOf() {
cout << "Derived::NameOf\n";
}
void Derived::InvokingClass() {
cout << "Invoked by Derived\n";
}
Main
int main() {
// Declare an object of type Derived.
Derived aDerived;
// Declare two pointers, one of type Derived * and the other
// of type Base *, and initialize them to point to aDerived.
Derived *pDerived = &aDerived;
Base *pBase = &aDerived;
// Call the functions.
pBase->NameOf(); // Call virtual function.
pBase->InvokingClass(); // Call nonvirtual function.
pDerived->NameOf(); // Call virtual function.
pDerived->InvokingClass(); // Call nonvirtual function.
}
In your example both foo() and foo2() will be from the Foo class.
int main()
{
Foo* f = new Foo;
f->foo(); // Foo::foo
f->foo2(); // Foo::foo2
return 0;
}
For you to illustrate the virtual behavior, you need to make an instance of the derived class
int main()
{
Foo* b = new Bar;
b->foo(); // Bar::foo
b->foo2(); // Foo::foo2
static_cast<Bar*>(b)->foo2(); // Bar::foo2
return 0;
}
Notice in the latter case, since b is actually a Bar, it invokes the overriden virtual method foo. But since foo2 isn't declared virtual and b is a Foo, it will invoke Foo::foo2. However, if we cast f to a Bar, it will invoke Bar::foo2
virtual keyword tells compiler for dynamic binding.
To view dynamic binding in action instantiate Foo pointer with Bar object , refer below code.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class Foo
{
public:
virtual void foo(){std::cout<<"Foo foo"<<std::endl;};
void foo2(){std::cout<<"Foo foo2"<<std::endl;};
};
class Bar : public Foo
{
public:
void foo(){std::cout<<"Bar foo"<<std::endl;};
void foo2(){std::cout<<"Bar foo2"<<std::endl;};
};
int main()
{
Foo* f = new Bar;
f->foo();
f->foo2();
return 0;
}
A class which declares or inherits virtual functions has something called a vtable which is used to look up which function to call when you invoke a virtual function. In effect, this table contains pointers to all the virtual functions in the class, something like this (pseudo-code - this may or may not compile):
class Foo {
void foo_impl(){std::cout<<"Foo foo"<<std::endl;}
struct {
void (*foo_ptr)();
} vtable;
public:
Foo(){vtable.foo_ptr = &Foo::foo_impl;}
void foo(){vtable.foo_ptr();}
void foo2(){std::cout<<"Foo foo2"<<std::endl;}
};
class Bar : public Foo {
void foo_impl(){std::cout<<"Bar foo"<<std::endl;}
public:
Bar(){vtable.foo_ptr = &Bar::foo_impl;}
void foo2(){std::cout<<"Bar foo2"<<std::endl;}
};
Thus, when you call a virtual function, the address is first looked up in the vtable, so if you assign a Bar bar; Foo& foo = bar;, then foo.foo() calls Bar's version of foo() instead of Foo's version.
The code below surprisingly compiles in VS 2012.
Method C::f() overrides methods in both base classes.
Is this standard behavior? I looked into C++11 standard, and didn't find any explicit mentioning of such situation.
class A { virtual void f() = 0; };
class B { virtual void f() = 0; };
class C : public A, public B {
virtual void f() override { }
};
Yes. The standard says, in C++11 10.3/2
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name [etc.] as Base::vf is declared, then [...] it overrides Base::vf.
There are no special cases for multiple base classes, so a function declared in the derived class will override a suitable function in all base classes.
Herb Sutter explains how to deal with this here.
According to the article:
class B1 {
public:
virtual int ReadBuf( const char* );
// ...
};
class B2 {
public:
virtual int ReadBuf( const char* );
// ...
};
class D : public B1, public B2 {
public:
int ReadBuf( const char* ); // overrides both B1::ReadBuf and B2::ReadBuf
};
This overrides BOTH functions with the same implementation
In C++, let's say I have a class Derived that implements an interface class BaseInterface, where BaseInterface has only pure virtual functions and a virtual destructor:
class BaseInterface
{
public:
virtual void doSomething() = 0;
~BaseInterface(){}
};
class Derived : public BaseInterface
{
public:
Derived() {}
~Derived(){}
protected:
virtual void doSomething();
private:
int x;
};
No classes outside the Derived class hierarchy should call Derived::doSomething() directly, i.e., it should only be accessed polymorphically through the BaseInterface class. To enforce this rule, I have made Derived::doSomething() protected. This works well, but I'm looking for opinions pro/con regarding this approach.
Thanks!
Ken
I think you're looking for the non-virtual interface (NVI) pattern: a public non-virtual interface that calls a protected or private virtual implementation:
class BaseInterface
{
public:
virtual ~BaseInterface(){}
void doSomething() { doSomethingImpl(); }
protected:
virtual void doSomethingImpl() = 0;
};
class Derived : public BaseInterface
{
public:
Derived() {}
virtual ~Derived(){}
protected:
virtual void doSomethingImpl();
private:
int x;
};
If it is part of the interface, why would you not want users to call it? Note that as it is, they can call it: static_cast<BaseInterface&>(o).doSomething() is just an awkward way of saying o.doSomething(). What is the point of using the interface... if the object fulfills the interface, then you should be able to use it, or am I missing something?
Since you are not actually blocking anyone from calling the methods, I don't see a point in making the code more complex (both the class and users of the class) for no particular reason. Note that this is completely different from the Non-Virtual Interface in that in this idiom virtual functions are not accessible publicly (at any level) while in your case, the intention is allowing access, and making it cumbersome.
What you are doing is also mentioned in standard ISO/IEC 14882:2003(E) 11.6.1 and believe you are correct. Other than the fact, the member function isn't pure virtual in the given example. It should hold for pure virtual functions too, AFAIK.
The access rules (clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it.
[Example:
class B
{
public:
virtual int f();
};
class D : public B
{
private:
int f();
};
void f()
{
D d;
B* pb = &d;
D* pd = &d;
pb->f(); // OK: B::f() is public,
// D::f() is invoked
pd->f(); // error: D::f() is private
}
—end example]
Access is checked at the call point using the type of the expression used to denote the
object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.
The key is the rest of your code. Only accept a BaseInterface* as an argument to any methods that require the doSomething() call. The client programmer is forced to derive from the interface to make his code compile.
This makes no sense to me. Regardless of which pointer you call doSomething(), you would still wind up with the method defined in most derived class. Consider the following scenario:
class BaseInterface
{
public:
virtual void doSomething() = 0;
~BaseInterface(){}
};
class Derived : public BaseInterface
{
public:
Derived() {}
~Derived(){}
virtual void doSomething(){}
private:
int x;
};
class SecondDerived : public Derived
{
public:
SecondDerived() {}
~SecondDerived(){}
private:
int x;
};
int main(int argc, char* argv[])
{
SecondDerived derived;
derived.doSomething(); //Derived::doSomething is called
BaseInterface* pInt = &derived;
pInt->doSomething(); //Derived::doSomething is called
return 0;
}