This question already has answers here:
Pure virtual destructor in C++
(2 answers)
Closed 8 years ago.
I am using Qt to develop an applicatio for which I am seeing a segmentation fault in my destructor of my virtual base class on exiting the application. I think it's to do with declaring the member variable static, but I'm not certain. Any pointers on what's going on would help. Below is my sample code. I have removed all the member functions for clarity.
In header file:
class Base : public QObject
{
public:
Base() {}
virtual ~Base() = 0; /// Fault occurs here in the debugger
};
class Child1: public Base
{
public:
Child1() {}
~Child1() {}
};
class Service
{
public:
Service() {}
~Service() {}
private:
static Child1 m_base;
};
In source file:
Child1 Service::m_base;
When I exit the application I get a segmentation fault in the Base class destructor. Is it because m_base static member variable does not exist at the time the destructor is called, but it's virtual!
BTW, I got rid of the problem by making m_base a pointer to Base class and instantiating it in definition, but I'd still like to know what's wrong with the code above.
Thanks!
Your sample code is incorrect, because you cannot create an instance to Base, since it is abstract.
Please be more specific.
EDIT:
I'm still not sure how this compiles, but You will have to add the Base destructor implementation:
Base::~Base()
{
}
Related
This question already has answers here:
Does every object of virtual class have a pointer to vtable?
(9 answers)
Closed 6 years ago.
I've read a lot of posts and everyone says, that virtual table is per class, not per object and object only has _vtpr pointer to shared vtable. But please consider this example:
class Base
{
public:
virtual void func1(void) {}
virtual void func2(void) {}
private:
int dummy;
};
class Der1 : public Base
{
public:
virtual void func1(void) {}
private:
int dummy;
};
class Der2 : public Base
{
public:
virtual void func2(void) {}
private:
int dummy;
};
int main(void)
{
Base * obj1 = new Der1;
Base * obj2 = new Der2;
}
Does obj1 and obj2 relates to that one unique Base class vtable? I believe the answer is no, but can you please explain? And if both of these objects do relate to the same vtable, how it is determined which methods to be called? For example, obj1->func1 reference is different than obj2->func1.
UPDATE:
What operations are executed when doing Base * obj1 = new Der1;? Can someone write a pseudo code for these actions?
I hope the following illustration will help. Derived classes just copy the virtual table of base class, but they may modify the appropriate entry. The red part shows that given class has modified the entry in v-table. So, when instance of derived class is created, the modified table (specific to that class) is taken into consideration.
It is up to the compiler how duplicity of base class is handled (if base class has large number of functions - would derived have copy of entire virtual function table, and would modify the entries?).
IMO, compiler will simply copy entire table for each derived class to keep things simple. Searching appropriate method to call then becomes simple.
This question already has answers here:
C++ virtual function from constructor [duplicate]
(7 answers)
Closed 9 years ago.
I have this layout
class Base {
public:
virtual void Initialize() { // base Implementation }
Base() { Initialize(); }
};
class der_1 : public Base
{
public:
der_1() : Base() {}
virtual void Initialize() { // der_1 Implementation }
};
class der_2 : public Base
{
public:
der_2() : Base() {}
virtual void Initialize() { // der_2 Implementation }
};
Now, whenever I create a new object of class der_1 or der_2, I will end up calling the base implementation of Initialize(). Apparently, I can't call a virtual function while the object is being created.
As of now, I am calling the Initialize function after I create the object of type der_1 or der_2, which doesn't seem a correct practice to me as that will couple the Initialize function call to each time an object is created.
Can someone suggest me better alternatives?
During the constructor call, the object "is" still only an instance of the base class, so it does know about your overloaded Initialize() function.
There are some suggestions for dealing with the situation here:
C++ virtual function from constructor
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why is this not allowed in C++?
Why is this not allowed in C++...??
class base
{
private:
public:
void func()
{
cout<<"base";
}
};
class derived : private base
{
private:
public:
void func()
{
cout<<"derived";
}
};
int main()
{
base * ptr;
ptr = new derived;
((derived *)ptr)->func();
return 0;
}
I am getting an error
**61 C:\Dev-Cpp\My Projects\pointertest.cpp `base' is an inaccessible base of `derived'**
My question is that since func() is defined public in derived class and the statement
((derived *)ptr)->func(); is trying to display the func() of derived..Why is there an accessible issue due to mode of inheritance..How does mode of inheritance(private) affects the call although I already have public derived func() in derived class..?
If mode of inheritance is changed to public I get my desired result..But a case where func() is private in base(so as func() of base is not inherited) and also func() is public in derived and mode of inheritance is public why still am I getting my desired result..Shouldn I be getting an Compile error as in the previous case ??
I am totally confused ..Please tell me how the compiler works in this case..??
You can't let the base pointer point to the derived object when there is private inheritance.
Public inheritance expresses an isa relationship. Private inheritance on the other hand expresses a implemented in terms of relationship
Ther compile error refers to the line:
ptr = new derived;
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Calling virtual functions inside constructors
class Base
{
virtual void method()
{ cout << "Run by the base."; };
public:
Base() { method(); };
};
class Derived: public Base
{
void method()
{ cout << "Run by the derived."; };
};
void main()
{
Derived();
}
Output:
Run by the base.
How can one have the derived method run instead, without making a derived constructor?
Calling virtual functions inside constructors
http://www.artima.com/cppsource/nevercall.html
You can't since the "derived" part of the object has not been constructed yet so calling a member function from it would be undefined behavior.
You can't do this without adding extra code.
A common way to achieve this is to use a private constructor and a create function that first calls the constructor (via new) and then a second finish_init method on the newly created object. This does prevent you from creating instances of the object on the stack though.
Maybe I am wrong, but this seems to be a very basic question. Suddenly my inheritance chain stopped working. Writing a small basic test application proved that it was me that was wrong (so I can't blame the compiler).
I have a base class, with the default behavior in a virtual function. A child class derives from that and changes the behavior.
#include <iostream>
class Base
{
public:
Base() { print(); }
~Base() {}
protected:
virtual void print() { std::cout << "base\n"; }
};
class Child : public Base
{
public:
Child() {}
~Child() {}
protected:
virtual void print() { std::cout << "child\n"; }
};
int main()
{
Base b;
Child c;
}
This prints:
base
base
When a Child instance is created, why is Base::print() called? I thought that by using the virtual keyword, the function can be replaced for the derived class.
At what point did I get myself confused?
You are calling a virtual method in the constructor, which is not going to work, as the child class isn't fully initialized yet.
See also this StackOverflow question.
Although your current problem is the virtual method call from a constructor that others have mentioned, I noticed that you didn't make the destructors virtual. That's normally a bad thing. In your case, the destructors are nops and there are no members that are objects with destructors,... but if your code changes then it's easy for bad things to happen.