When I have something like this, and when I have a* mya=new c(); and I call a->displayStuff it calls Class a method, and when virtual is in Class a instead of Class b, it calls Class b method.
Since Class c has no implementation of this method, what is the rule applied here?
class a
{
public:
void displayStuff() {}
//other methods
};
class b:public a
{
public:
virtual void displayStuff() {}
//other methods
};
class c:public b
{
//other methods
};
In the first your case class A has no virtual function. So its non-virtual function displayStuff will be called. in the second case when you added function specifier virtual to the function in class A the corresponding function inclass B redefines this function. So in the second case the function of class B is called because the table of virtual function pointers contains a pointer to the function defined in class B.
Since Class c has no implementation of this method, what is the rule
applied here?
The rule of inheritance applies. Based on the visibility of the inherited member and the inheritance type, the members visible in Class B would be visible in Class C. In this case, as you are inheriting publicly, all public members would be visible publicly. So, the public virtual member function in Class B would be visible as a public virtual function in Class C.
Exactly, but when to use what and why when I have multiple levels of
inheritance?
Its a design decision. Remember, a non virtual member function is bound at compile time, so any Function Call via a base pointer cannot be resolved until you intend to call the function.
Consider the scenario
Base
public: foo
/ \
/ \
/ \
/ \
/ \
Derived1 Derived2
public: foo public: foo
Base *p;
std::cin>>cond;
if (cond)
p = new Derived1();
else
p = new Derived1();
p->foo();
In the above code, the decision to call foo() (Derived1::foo or Derived2::foo), depends on some external condition which cannot be determined at runtime. The only way to make this possible is create a vTable which can only be forced to be created if we make at-least one function in a class virtual (Note any virtual function in the base class continues to remain virtual in the derived class).
Related
I was wondering how can one explain this mechanism:
class Base{
class Other;
virtual void test() = 0;
};
class Other: Base{
virtual void test() override;
};
void Other::test(){ /*do something*/}
It looks like I have a base class called Base. It contains of a nested class which inherits from the Base. So if I call:
Base obj;
obj.test(); <-- it trigers the test() function from the Other class, doesn't it?
What is the difference between the given example and the following:
class Base{
virtual void test() = 0;
};
class Other: Base{
virtual void test() override;
};
void Other::test(){ /*do something*/}
what would be the benefit of hidding the Other class in the Base class?
class Base{
virtual void test() = 0;
};
Base obj; // #0
#0 is ill-formed as Base is an abstract class, as it has at least one pure abstract member function.
Abstract class
Defines an abstract type which cannot be instantiated, but can be
used as a base class.
A pure virtual function is a virtual function whose declarator has the
following syntax:
declarator virt-specifier(optional) = 0
[...] An abstract class is a class that either defines or inherits
at least one function for which the final overrider is pure virtual.
Dynamic dispatch on polymorphic objects happens when you are dispatching to a virtual function from a base pointer or reference, which (for the specific runtime call) references a derived object.
In the following example:
struct Base {
virtual void test() const = 0;
};
struct A final : public Base {
void test() const override {}; // #1
};
struct B final : public Base {
void test() const override {}; // #2
};
void f(Base const& b) {
b.test(); // #3
}
the call to the virtual member function test() at #3 can dispatch to either A::test() or B::test(), depending on the argument to the function f.
f(A{}); // 'test()' call in 'f' dispatches to #1
f(B{}); // 'test()' call in 'f' dispatches to #2
what would be the benefit of hidding the Other class in the Base class?
In your original example, the Base class declares a nested class (but does not define it) to itself, meaning the Other class declared in Base is not the same as the Other class that derives from it.
Declaring nested classes within a class is a separate topic entirely orthogonal to class inheritance hierarchies
A forward declaration outside of a base class that intends to forward declare a derived class that the base class thinks may derive from it would be an anti-pattern, as the whole point with abstract (interface) classes is to provide a public client API that can be used polymorphically by different derived classes. In other words, a base class should generally never (need to) know about its derived classes (save for the special case of static polymorphism via the curiously recurring template pattern).
The declaration of class Base::Other at line 2 in your first code example, has nothing to do with the declaration of class Other in line 5 of your first code example.
That is, the forward declaration of Base::Other does not match class Other.
There is benefit in having nested classes (for example, some implementations of the pimpl idiom do that), but to define the nested class, you would have to define it with:
class Base::Other {...}; // explicit specification of Base here
I have a question about using the keyword final in C++. I understand that virtual function is a member function that is declared in the base class, and it is expected to be overridden in the derived classes. By dynamic binding, an appropriate method will be called, depending on the type of the object responsible for the call. However, to prevent a member function in a base class from being overridden in any derived class, we will use the final keyword.
void startEngine() final;// Compile error!
virtual void startEngine() final; //No error
Why we use "final" to PREVENT a member function in the base class from being overridden in derived class meanwhile we still have to use the keyword VIRTUAL (ALLOW to override) together.
I tried to delete the word virtual, but I got a compile error: "nonvirtual function cannot be declared with 'final' modifier"
First at all, we only can stop overriding functions if they can be overridden at all. So final only makes sense on virtual functions at all.
Still, final applied on a single class's virtual function might appear pretty meaningless. But if you consider a more complex hierarchy, matter changes:
class Parent
{
public:
virtual ~Parent() = default;
virtual void f();
};
class Child : public Parent
{
public:
void f() final; // f IS virtual already...
};
class GrandChild : public Child
{
// cannot override f any more – while Child still could!
};
Additionally, consider the following:
class Base
{
public:
virtual ~Base() = default;
void f(); // non-virtual! (i. e. cannot be overridden)
};
class Derived : public Base
{
public:
void f(); // does not override, but HIDEs Base::f!!!
};
Declaring Base::f both virtual and final would prevent hiding as well (but not overloading).
Actually, again this scenario rather makes sense if Base itself already inherited from another polymorphic class. If not and Base is not intended to be inherited, I'd not introduce any virtual functions at all (virtual function calls are more costly than normal function calls!). If then a user still inherits and hides a function – well, his own responsibility...
I just find out that overriding a private function to a public one from base object is allowed in C++ since Visual Studio produces 0 warning. Is there any potential danger to doing that?
If there isn't, what's the difference between declaring a virtual function in private, protected and public in a base object?
what's the difference between declaring a virtual function in
private, protected and public in a base object?
The difference is that a private virtual function can be called only from a base class. This can be useful if the function is not a part of an external class interface, and is only used by base class. So that users call (some other) base class' member, and that member calls the virtual function. For example:
class Base {
virtual void stage1()=0; // derived classes override this
virtual void stage2()=0;
public:
void run() { stage1(); stage2(); } // users call this
};
Moreover, there is a point of view that you should not make your virtual functions public at all, because the fact that they are virtual is internals of the class and its subclasses, and the users should not be aware of that. It is rarely that the same function must be overridden and callable from external code. This allows the base class to control which (virtual) functions can be called from which (non-virtual) public method, making maiteinance easier.
See more details in this article by Herb Sutter:
...each [public] virtual
function is doing two jobs: It's specifying interface because it's
public...; and it's specifying implementation detail,
namely the internally customizable behavior... That a public virtual
function inherently has two significantly different jobs is a sign
that it's not separating concerns well and that we should consider a
different approach. What if we want to separate the specification of
interface from the specification of the implementation's customizable
behavior?
...
In summary, prefer to make base class virtual functions private (or
protected if you really must). This separates the concerns of
interface and implementation, which stabilizes interfaces and makes
implementation decisions easier to change and refactor later.
However, I am not qualified to say whether this is really widely used...
Is there any potential danger to doing that?
I don't think so, because you are still very limited:
class Base
{
private:
virtual void foo(){}
};
class Derived1 : public Base
{
public:
virtual void foo(){ Base::foo(); }
};
class Derived2 : public Base
{
public:
virtual void foo(){}
};
int main()
{
Derived1 d1;
d1.foo(); //error
Base * d2 = new Derived2();
d2->foo(); //error
}
So at best you will be able to call the overloaded function (if it doesn't call the function from the base class from itself), but the function of the base class will still have the same visibility, and will be inaccessible.
When changing access visibility by overriding in derived class, base class visibility doesn't change:
So with:
class Base {
public:
virtual ~Base() = default;
protected:
virtual void foo() = 0;
};
class Derived : public Base {
public:
void foo() override {};
};
Then
Derived d;
Base& b = d;
d.foo(); // valid
b.foo(); // invalid
If there isn't, what's the difference between declaring a virtual function in private, protected and public in a base object?
It depends on how you access the function. The type of the object/pointer you use determines whether you can access the function.
class Base
{
public:
virtual void foo() {}
};
class Derived : public Base
{
private:
virtual void foo() {}
};
int main()
{
Derived* dptr = new Derived;
Base* bptr = dptr;
dptr->foo(); // Can't use it. Derived::foo is private
bptr->foo(); // Can use it. Base::foo is public.
}
Compiler message, using g++ 4.9.3.
socc.cc: In function ‘int main()’:
socc.cc:12:20: error: ‘virtual void Derived::foo()’ is private
virtual void foo() {}
^
socc.cc:20:14: error: within this context
dptr->foo(); // Can't use it. Derived::foo is private
A virtual function is a customization point for derived class implementations. If it is private then it's purely an implementation detail. Making it more accessible in a derived class then exposes an implementation detail, with all that that entails. In particular client code can come to depend on that detail so that the implementation can't be easily changed. It can also be easier for client tode to call in incorrect ways, than the originally intended interface, and it can yield results that are only valid in certain contexts, so that it's more brittle than the original interface.
Say we have this:
class A
{
public:
virtual void foo() = 0;
};
class B: public A
{
public:
virtual void foo() = 0;
};
The compiler throws no error, I guess its because B is also an abstract class and as such it does not have to implement foo from A.
But what does such a construct mean?
1) Does foo from B hide foo from A?
2) The first class which inherits from B and is not an abstract class, does it have to provide two implementations like:
class C: public B
{
public:
virtual void A::foo() {};
virtual void B::foo() {};
};
The compiler only complains if the implementation of B::foo() is missing, but it does not complain about a missing A::foo().
All in all: is this a way to hide pure virtual methods?
When you first declare:
class A
{
public:
virtual void foo() = 0;
};
you are declaring the method foo public, virtual and pure. When a class contains at least a pure method it's called abstract. What does it mean? It means that the class cannot be instantiated because it needs the pure methods implementations.
You can obviously inherit from an abstract class (I'd say that you are forced to do that, otherwise what would be the need of an abstract class you are not using, except for providing an interface to inherit from?) and you can also inherit from an abstract class and not implement some or all of the pure methods of the parent class; in this case the child class is abstract as well, which is the case of your class B:
class B: public A
{
public:
virtual void foo() = 0;
};
In B you could easily omit the virtual void foo() = 0; declaration because the definition is already inherited from the base class. In this case class B is an abstract class and therefore cannot be instantiated, just like A.
To answer your questions more directly:
Does foo from B hide foo from A?
No, it does not. They both are declaring a pure method (which is in fact the same method), therefore there's nothing to really hide.
The first class which inherits from B and is not an abstract class, does it have to provide two implementations like the one provided?
No, of course not. As stated above, they are the same method, therefore if class C have to provide an implementation for foo it should just implement foo:
class C: public B
{
public:
virtual void foo() {};
};
0) The compiler throws no error ...
It will throw an error when you try to instantiate an object from A or B which they're abstract. Not when you're inheriting and declaring them.
1) Does foo from B hide foo from A?
No. It overtides A::foo not hides it.
2) The first class which inherits from B and is not an abstract class,
does it have to provide two implementations ...
No. Just override foo and make one implementation for it.
class C : public B
{
public:
virtual void foo()
{
std::cout << "ABCD" << std::endl;
}
};
int main()
{
C c;
A *a = &c;
a->foo(); // Prints ABCD string and proofs B::foo doesn't hide A::foo
}
I compiled your code with gcc 4.5.3, it gave the following error messages:
error: cannot define member function ‘A::foo’ within ‘C’
error: cannot define member function 'B::foo' within 'C'
In you example, both class A and B are abstract classes since foo is pure virtual. They only define that derived class of B should implement the behavior of foo since there is no default behavior to use (if the derived class is not abstract anymore).
Question 1:Does foo from B hide foo from A?
Since foo in B and A has exactly the same name, same signature and foo is virtual in base class, so it is not hiding, it is overriding. FYI: A derived class's function overrides a base class function if the signature is the same and it's declared virtual in the base class. If you call it
through a pointer or a reference to the base class, the function in the
derived class is called. It "overrides" the one in the base class.
Hiding only comes into play if you call a non-virtual function through a
pointer or reference or directly with an object of the derived class. A
derived class' function hides all base class functions with the same name.
Question 2: The first class which inherits from B and is not an abstract class, does it have to provide two implementations
No. You can do the following:
class C: public B
{
public:
virtual void foo()
{
cout << "foo defined in c" <<endl;
}
};
Here is a sample of code that annoys me:
class Base {
protected:
virtual void foo() = 0;
};
class Derived : public Base {
private:
Base *b; /* Initialized by constructor, not shown here
Intended to store a pointer on an instance of any derived class of Base */
protected:
virtual void foo() { /* Some implementation */ };
virtual void foo2() {
this->b->foo(); /* Compilator sets an error: 'virtual void Base::foo() is protected' */
}
};
How do you access to the protected overrided function?
Thanks for your help. :o)
Protected members in a base-class are only accessible by the current object.
Thus, you are allowed to call this->foo(), but you are not allowed to call this->b->foo(). This is independent of whether Derived provides an implementation for foo or not.
The reason behind this restriction is that it would otherwise be very easy to circumvent protected access. You just create a class like Derived, and suddenly you also have access to parts of other classes (like OtherDerived) that were supposed to be inaccessible to outsiders.
Normally, you would do it using Base::foo(), which refers to the base class of the current instance.
However, if your code needs to do it the way you're trying to and it's not allowed, then you'll need to either make foo() public or make Derived a friend of Base.
One solution would be to declare a static protected function in Base that redirects the call to the private / protected function (foo in the example).
Lets say:
class Base {
protected:
static void call_foo(Base* base) { base->foo(); }
private:
virtual void foo() = 0;
};
class Derived : public Base {
private:
Base* b;
protected:
virtual void foo(){/* Some implementation */};
virtual void foo2()
{
// b->foo(); // doesn't work
call_foo(b); // works
}
};
This way, we don't break encapsulation because the designer of Base can make an explicit choice to allow all derived classes to call foo on each other, while avoiding to put foo into the public interface or explicitly turning all possible subclasses of Base into friends.
Also, this method works regardless of whether foo is virtual or not, or whether it is private or protected.
Here is a link to a running version of the code above and here another version of the same idea with a little more business logic.
It's a bit fragile, but with the classes you defined here, won't this work?
virtual void foo2() {
reinterpret_cast<Derived *>(this->b)->foo();
}
The reinterpret_cast points at the VTABLE for the base object, and calls it through this members accessor.
You call base functions explicitly with the scope operator (Base::foo()). But in this case, the Base class doesn't define foo (it's pure virtual), so there's actually no function to execute when you say this->b->foo(); since b is a pointer to Base and not Derived.
How do you access to the protected
overrided function?
--- from where?
You can access a protected member only via inheritance (apart from the methods of the same class). Say for example you have a class Derived1 which inherits from Derived, then objects of Derived1 can call foo().
EDIT: MSDN article on protected access specifier.