This question already has answers here:
Calling child method from parent destructor in C++
(3 answers)
Closed 1 year ago.
#include <iostream>
using namespace std;
class Super {
public:
virtual ~Super() {
func();
}
virtual void func() {
cout << "super-class" << endl;
}
};
class Child : public Super {
public:
virtual void func() override {
cout << "child-class" << endl;
}
};
int main(void) {
Super super;
Child child;
return 0;
}
In this code, the default destructor of class Child is calling its super class Super's func() instead of its own overrided func(). And the output was:
super-class
super-class
I've tried this solution below.
#include <iostream>
using namespace std;
class Super {
public:
virtual ~Super() {
func();
}
virtual void func() {
cout << "super-class" << endl;
}
};
class Child : public Super {
public:
virtual ~Child() {
func();
}
virtual void func() override {
cout << "child-class" << endl;
}
};
int main(void) {
Super super;
Child child;
return 0;
}
And the output was:
child-class
super-class
super-class
But is there a way to let class Child automatically call its own func() in its destructor without virtual ~Child()?
By the time a base class destructor has started running, the derived class(es) have already been fully destructed. It (they) no longer exist(s). They cannot be called into. They are EX-objects! (Loosely paraphrasing Herb, paraphrasing the John.)
Level by level, as the object dies, the parts of it that have been destroyed are not left behind; they no longer exist. The type is adjusted accordingly upwards, and virtual calls resolve to the type being destroyed, until nothing is left of that object but a pile of bits.
Related
This question already has answers here:
What if the virtual destructor defined in derived class, but not the top of hierarchy? C++
(4 answers)
Closed 3 years ago.
I am just trying to understand some concepts of inheritance/polymorphism and tried to inherit a class from std::string as shown below:
#include <iostream>
using namespace std;
class MyClass : public std::string
{
virtual ~MyClass()
{
cout << "Inside Virutal Destructor" << endl;
}
};
int main()
{
string *s = new MyClass();
delete s;
cout << "Program started" << endl; //NEVER REACHES HERE
}
QUESTION: With the above code, I was expecting a call to the virtual destructor at the line delete s but as soon as the program reaches there, the program enters into some undefined state (i.e. doesn't crash, doesn't go forward). Where is the program stuck?
The standard class template std::basic_string does not have a virtual destructor. So the class does not have a pointer to the destructor in the table of virtual function pointers. As a result the virtual destructor of the derived class will not be called.
Consider the following demonstrative program
#include <iostream>
struct A
{
void f() const { std::cout << "A::f()\n"; }
};
struct B : A
{
virtual void f() const { std::cout << "virtual B::f()\n"; }
};
struct C : B
{
void f() const override { std::cout << "virtual C::f()\n"; }
};
int main()
{
C c;
A *ac = &c;
B *bc = &c;
ac->f();
bc->f();
return 0;
}
Its output is
A::f()
virtual C::f()
Class A has a non-virtual function f.
Class B has a virtual function f that hides the non-virtual function of the class A and does not override it.
Class C overrides the virtual function of the class B.
Reading through a text book, I have come away with the impression that overriding virtual functions only works when using a pointer or reference to the object. The book demonstrates the creation of a pointer of the base class type pointed to an object the derived class type, and uses that to demonstrate a virtual function override.
However, I've now come across the following. Not a pointer in sight, and I was expecting that making function1 virtual would not make a difference, but it does. I'm clearly missing something here and would appreciate an explanation as to what it is. Sorry if my explanation isn't clear; also I expect this has been asked before, but was unable to come up with what to search on.
using namespace std;
class ClassA
{
public:
void function1(); // virtual or not?
void function2();
};
class ClassB : public ClassA
{
public:
void function1();
};
int main()
{
ClassA objA;
ClassB objB;
objA.function1();
cout << "\n";
objA.function2();
cout << "\n";
objB.function1();
cout << "\n";
objB.function2(); // Fourth call
cout << "\n";
}
void ClassA::function1() { cout << "ClassA::function1\n"; }
void ClassA::function2()
{
cout << "ClassA::function2\n";
function1(); // For the fourth call ClassA::function1()
// is called if ClassA::function1() is not virtual
// but ClassB:function1() is called if it is. Why?
}
void ClassB::function1() { cout << "ClassB::function1\n"; }
Many thanks for any help.
It's not a virtual function as it is not marked as one. It's simply a public function accessible from a derived class / object. Your code is not exhibiting polymorphic behavior either. That being said none of your functions are virtual nor overriding. Trivial example for polymorphic installation would be:
#include <iostream>
#include <memory>
class ClassA {
public:
virtual void function1() { // now virtual
std::cout << "ClassA::function1\n";
}
};
class ClassB : public ClassA {
public:
void function1() override {
std::cout << "ClassB::function1\n";
}
};
int main() {
std::unique_ptr<ClassA> p = std::make_unique<ClassB>();
p->function1(); // now calls class B function, overrides class A behavior
}
or through references:
int main() {
ClassB objB;
ClassA& ro = objB;
ro.function1(); // now calls class B function, overrides class A behavior
}
There is little benefit in marking functions as virtual and override if you are not utilizing polymorphic behaviour.
Example of virtual without explicit pointers :
class A
{
public:
virtual void f1()
{
cout << "A::f1()" << endl;
}
void f2()
{
f1();
}
};
class B : public A
{
public:
void f1() override
{
cout << "B::f1()" << endl;
}
};
int main()
{
A a;
B b;
a.f2();
b.f2();
}
function1 is not virtual, obj2 calls the classB function1 because it is a clasB object, the compiler first looks at the most-derived type for a function, then the leftmost base (and on through the bases of that base), and then the next base in multiple inheritance situations. If you took a classA * to obj2 and called function1 it would call the classA function1.
This question already has answers here:
Calling a virtual function from the constructor
(3 answers)
Closed 5 years ago.
#include <iostream>
class Base {
public:
virtual void method() {
std::cout << "Base" << std::endl;
}
Base() {
method();
}
};
class Sub : public Base {
public:
virtual void method() {
std::cout << "Sub" << std::endl;
}
Sub() : Base() {
}
};
int main(void) {
Base *b = new Sub();
delete b;
system("PAUSE");
return 0;
}
Output: "Base"
What do i have to change to make the Base call the Sub Method instead of the Base?
This is probably a duplicate and a beginner-question, but i couldn't find an answer to this problem.
Also a suggestion for a better title is welcome as the current one might be wrong.
a) because the standard says so.
b) philosophically, because Sub at this point has not had its constructor called (inherited objects are constructed in a depth-first manner), so calling Subs version of method would surprise the author of Sub.
This question already has answers here:
accessing a protected member of a base class in another subclass
(8 answers)
Closed 7 years ago.
I always thought that I understood inheritance, but obviously I don't. I would like to call a protected member function of another instance of the same parent class from a child class like in the following example code:
#include <iostream>
class Parent {
protected:
void doStuff(){
std::cout << 5 << std::endl;
}
};
class Child : public Parent {
public:
void pubfunc(Parent* p){
p->doStuff();
}
};
int main(){
Child* c = new Child();
Parent* p = new Parent();
c->pubfunc(p);
return 0;
}
However, compilation of this code fails with:
In member function ‘void Child::pubfunc(Parent*)’:
error: ‘void Parent::doStuff()’ is protected
error: within this context
I wouldn't want to make the Child class a friend of the Parent class to avoid forward declarations and forward includes of child classes as much as possible. Also, I don't want to make doStuff public, because it can really mess up the internal structure of Parent when used in the wrong circumstances.
Why does this error happen, and what is the most elegant way to solve it?
Mostly the problem is that if C++ allowed you to access the non-public members of the referent of a base class pointer directly, then you could gain easy access to the data of an object simply by deriving from a common base.
Still this is a known loophole in the C++ type system, as shown below, where you can gain that access without modifying the base class, and without using casts or anything like that.
On the third and gripping hand, what you should do is to support the intended usage directly in the base class, by adding a static member function there, as follows:
#include <iostream>
using namespace std;
class Base
{
protected:
void doStuff()
{
cout << 5 << endl;
}
static void doStuff( Base* p ) { p->doStuff(); }
};
class Derived : public Base
{
public:
void pubfunc( Base* p )
{
doStuff( p );
}
};
auto main() -> int
{
Derived d;
Base b;
d.pubfunc( &b );
}
In my humble opinion this is most clear and elegant.
But for completeness, the type system loophole:
#include <iostream>
using namespace std;
class Base
{
protected:
void doStuff()
{
cout << 5 << endl;
}
};
class Derived : public Base
{
public:
void pubfunc( Base* p )
{
(p->*&Derived::doStuff)();
}
};
auto main() -> int
{
Derived d;
Base b;
d.pubfunc( &b );
}
I recommend the static member function, though.
Protected members are accessible in the class that defines them and in classes that inherit from that class. Sometimes it causes people to be confused when they see this kind of errors. But in fact you call doStuff function for Parent object, it doesn't meter if function call done inside inherited class. The result will be the same if you call doStuff function from main().
class Parent
{
protected:
virtual void doStuff()
{
std::cout << 5 << std::endl;
}
};
class Child : public Parent
{
protected:
void doStuff() override
{
std::cout << 8 << std::endl;
}
public:
void pubfunc(Parent* p)
{
((Child*)p)->doStuff();
}
};
int main()
{
Child* c = new Child();
Parent* p = new Parent();
c->pubfunc(p); // will print 5
c->pubfunc(c); // will print 8
return 0;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calling virtual functions inside constructors
main.cpp
#include <iostream>
class BaseClass {
public:
BaseClass() {
init();
}
virtual ~BaseClass() {
deinit();
}
virtual void init() {
std::cout << "BaseClass::init()\n";
}
virtual void deinit() {
std::cout << "BaseClass::deinit()\n";
}
};
class SubClass : public BaseClass {
public:
virtual void init() {
std::cout << "SubClass::init()\n";
}
virtual void deinit() {
std::cout << "SubClass::deinit()\n";
}
};
int main() {
SubClass* cls = new SubClass;
delete cls;
return 0;
}
Why is init() and deinit() not properly overriden and the BaseClasses' methods are called instead of the SubClasses ones? What are the requirements to make it work?
BaseClass::init()
BaseClass::deinit()
Because you are calling a virtual method inside a constructor. While constructing Base class the derived one (SubClass) isn't still constructed, so actually it doesn't still exist.
It's generally a good practice to avoid calling virtual methods inside constructors.
They are overridden just fine.
But you've invoked them from the base constructor, and when the base constructor is executing, the derived part of the object does not yet exist.
So this is a largely a safety feature, and it's mandated by the C++ standard.