Is it valid to override virtual function with pure specifier? [duplicate] - c++

This question already has answers here:
Can I override a virtual function with a pure virtual one?
(2 answers)
Turning a non-pure virtual function into pure in a subclass
(2 answers)
Closed 2 years ago.
Note: I do not ask whether or not this is reasonable thing to do or if this is good design. I'm just asking if this is well-defined behaviour and if the results are as expected.
I came upon a following class hierarchy:
struct A
{
virtual void foo() = 0;
};
struct B: public A
{
void foo() override
{
std::cout << "B::foo()\n";
}
};
struct C: public B
{
virtual void foo() = 0;
};
struct D: public C
{
void foo() override
{
std::cout << "D::foo()\n";
}
};
int main()
{
A* d = new D;
d->foo(); //outputs "D::foo()"
// A* c = new C; // doesn't compile as expected
}
Is this code well defined? Are we allowed to override definition with pure-specifier?

[class.abstract/5] of the current draft Standard:
[Note: An abstract class can be derived from a class that is not abstract, and a pure virtual function may override a virtual function which is not pure. — end note]
The very same note is included even in the C++11 Standard. So, the answer is yes, it is valid.

Related

Polymorphism in C++ (unexpected behaviour) [duplicate]

This question already has answers here:
What's the difference between the Derived class override the base class's virtual function with or not with a "virtual" prefix? [duplicate]
(2 answers)
Closed 5 years ago.
I have three following classes:
class A
{
private:
std::string device;
public:
std::string getDeviceType() { return device; };
void setDeviceType(std::string device) { device = device; };
virtual void doSomething() = 0;
virtual void doSomething2() = 0;
};
class B: public A
{
private:
public:
B(){ ; };
virtual ~B(){ ; };
void doSomething() { std::cout << "I am usual B" << std::endl; };
void virtual doSomething2() { std::cout << "I am usual B" << std::endl; };
};
class C : public B
{
private:
public:
C(){ ; };
~C(){ ; };
void doSomething() { std::cout << "I am C" << std::endl; };
void doSomething2() { std::cout << "I am C" << std::endl; };
};
main:
B *myHandler = new C();
myHandler->doSomething();
myHandler->doSomething2();
but output is not as expected, my expected output was I am usual B and then I am C, because doSomething() is a non virtual member of class B. But the real output was I am C and then I am C. Do you know why?
because of doSomething() is non virtual member of class B
This is where you are mistaken. In A you declare doSomething() as virtual. That means that it is implicitly marked virtual in classes that derive from it. So doSomething() in B is virtual which means you will call C's doSomething().
The reason is that doSomething is marked as virtual in class A. So it remains virtual in classes B and C because they inherit from class A.
As this function is virtual, it is called according to the real type of the object, which is C in your case, and you get the output: I am C.
Once marked virtual, it remains virtual in all derived classes.
In C you overrode both doSomething() and doSomething2(). You instantiate C, so the methods of C are called in both cases.
If you omitted the override in C of doSomething(), the output would be as you expected it.
KR,
Melle

Virtual inheritance ambiguous function [duplicate]

This question already has answers here:
Virtual Inheritance: Error: no unique final overrider
(2 answers)
Multiple (diamond) inheritance compiles without "virtual", but doesn't with
(2 answers)
Closed 6 years ago.
I have this part of code
#include <iostream>
using namespace std;
class A {
public:
int i;
A(){i = 0; }
virtual void f() { cout << i; }
};
class B1 : virtual public A {
public:
B1() { f(); }
void f() { cout << i+10; }
};
class B2 : virtual public A {
public:
B2() { f(); }
void f() { cout << i+1; }
};
class C : public B1, public B2 {
public:
C() {}
};
void main(){
C c;
//c.A::f();
}
First, I understand the main idea behind using virtual inheritance (diamond) in order to create only one A object in memory.
In this example, I get compilation error in C class:
override of virtual function "A::f" is ambiguous
If I remove the virtual inheritance. The code compiles, there is no error in class C as before.
If I remove the comment from the last code line it still compiles. I understand that in this case the f() function that will be executed is the one from the first class that C inherits from.
Now, if I replace c.A::f() with c.f() I get a compilation error at this specific line.
Can someone please explain this behaviour and the differences between these cases?
The problem is with C not with your expression call. As f is virtual and redefined twice in B1 and B2 then the C class is malformed because a call to fwould be ambiguous (which override to choose?). Add an override of f in Cand everything will be ok.
Within the class C you must choose which variant of f to usr. That is, using B1::f; or using B2::f.

Why does an overridden virtual function get called in the base class during construction? [duplicate]

This question already has answers here:
C++ virtual function from constructor [duplicate]
(7 answers)
Closed 7 years ago.
There is a c++ program:
# include <iostream>
using namespace std;
class base
{
public:
base()
{
cout<<"base"<<endl;
f();
}
virtual void f() {
cout<<"base f"<<endl;
}
};
class derive: public base
{
public:
derive()
{
cout<<"derive"<<endl;
f();
}
void f() {
cout<<"derive f"<<endl;
}
};
int main()
{
derive d;
return 1;
}
and it outputs:
base
base f
derive
derive f
I am wondering why base f appears?
I quess in base the constrctor expands to:
cout<<"base"<<endl;
this.f();
But this should point to derive so why base f is print out?
During construction, in the baseclass constructor, the actual type of the object is base, even though it lateron continues to become a derived. The same happens during destruction, btw, and you can also verify the type using typeid.

Trouble with inheritance: Using pointers with class instantiation not working as expected [duplicate]

This question already has answers here:
Undefined symbols "vtable for ..." and "typeinfo for..."?
(5 answers)
Closed 8 years ago.
I'm getting the error undefined reference to 'vtable for Base'. I don't know what this means as I am not using anything called "vtable". Also, I don't exactly understand how making pointers and new Derived are affecting the program. Can anyone clear this up? Thanks.
#include <iostream>
using std::cout;
class Base { // undefined reference to 'vtable for Base'
public:
void f();
virtual void bar();
};
class Derived : public Base {
public:
void f();
void bar() {
cout << "I am bar";
}
};
int main() {
Derived d;
Base * b = &d;
b->bar();
}
You must implement virtual functions of classes you instantiate in order to compile. (or mark them pure virtual).
Just make bar empty in Base:
virtual void bar() {}
Or pure virtual (must be reimplemented in derived classes in order to instantiate them)
virtual void bar() = 0;
You have two problems. First, make the methods in Base pure virtual:
class Base {
public:
virtual void f()=0;
virtual void bar()=0;
};
Second, you need to implement f():
class Derived : public Base {
public:
void f(){}
void bar() {}
};

How to prevent a method from being overridden in derived class? [duplicate]

This question already has answers here:
Is there a way to prevent a method from being overridden in subclasses?
(14 answers)
Closed 7 years ago.
How can I enforce that a base class method is not being overridden by a derived class?
If you are able to use the final specifier from C++11 you can prevent derived classes from override that method. (Microsoft compilers appear to support the similar sealed with similar semantics.)
Here's an example:
#include <iostream>
struct base {
// To derived class' developers: Thou shalt not override this method
virtual void work() final {
pre_work();
do_work();
post_work();
}
virtual void pre_work() {};
virtual void do_work() = 0;
virtual void post_work() {};
};
struct derived : public base {
// this should trigger an error:
void work() {
std::cout << "doing derived work\n";
}
void do_work() {
std::cout << "doing something really very important\n";
}
};
int main() {
derived d;
d.work();
base& b = d;
b.work();
}
Here's what I get when I try to compile it:
$ g++ test.cc -std=c++11
test.cc:17:14: error: virtual function ‘virtual void derived::work()’
test.cc:5:22: error: overriding final function ‘virtual void base::work()’
If you make the method non-virtual, derived classes cannot override the method. However, in C++03 a class cannot override a method from a base class, and also prevent further derived classes from overriding the same method. Once the method is virtual, it stays virtual.
Don't make it virtual.
This won't prevent deriving from your class and hiding the function (by providing another member function with the same name). However, if your class is not meant to be derived anyway (no virtual destructor, no virtual member functions), that shouldn't be an issue.
well if you want to keep it public, dont declare it virtual.
EDIT: Srikanth commented wondering about overriding a private member function in a derived class.
class A
{
public:
virtual ~A(){};
void test()
{
foo();
};
private:
virtual void foo()
{
std::cout << "A";
};
};
class B : public A
{
public:
virtual void foo()
{
std::cout << "B";
};
};
void test()
{
B b;
A& a = b;
a.test(); // this calls the derived B::foo()
return 0;
}`
well as far as i know you can't do that on c++, you can try to declare it as private. . find more info on this link http://en.allexperts.com/q/C-1040/prevent-overriding-functions-derived.htm
Short answer: there is no need for that. Long answer you can do some twists, but is it worth it?