Destructor called two times in C++ - c++

I have a code with two classes like this:
Class A:
class A {
int a, b;
public:
A(int x, int y) {
a = x;
b = y;
}
~A() {
cout << "Exit from A\n";
}
void values() {
cout << a << "\n" << b << endl;
}
};
Class B:
class B :public A
{
int c;
public:
B(int x, int y, int z) :A(x, y)
{
c = z;
}
~B() {
cout << "Exit from B\n";
}
void values() {
A::values();
cout << c << endl;
}
};
And main function:
int main()
{
A testA(1, 2);
testA.values();
B testB(10, 20, 30);
testB.values();
}
That's what i got:
1
2
10
20
30
Exit from B
Exit from A
Exit from A
First is called destructor from class B, then from A twice. Why two times? I don't know how to change it.

There are 2 A objects created in main, testA, and the A base-subobject of testB. Both are destroyed at the end of main, in reverse order of how they are declared.
class A {
int a, b;
std::string msg;
protected:
A(int x, int y, std::string m) : a(x), b(y), msg(m) {}
public:
A(int x, int y) : A(x, y, "Exit from A\n") {}
virtual ~A() {
std::cout << msg;
}
virtual void values() {
std::cout << a << "\n" << b << std::endl;
}
};
class B :public A
{
int c;
public:
B(int x, int y, int z) : A(x, y, "Exit from B\n"), c(z) {}
void values() override {
A::values();
std::cout << c << std::endl;
}
};

You have Object testA which will call it's destructor from A (1).
You have Object testB which is derived from A so it will call destructor B (1) and destructor A (2).
This is exactly what your output says.

Related

C++ Multiple virtual inheritance, classes share the same subobject

I want to inherit 'x' from 'class B' and 'y' from 'class C' but both classes share the same 'A' subobject. Is there any solution?
#include <iostream>
class A {
protected:
int x;
int y;
public:
A() : x(10), y(10) {}
};
class B : virtual public A {
public:
B() {this->x = 20; this->y = 20;}
};
class C : virtual public A {
public:
C() {this->x = 30; this->y = 30;}
};
class D : public B, public C {
public:
D() {
this->x = this->B::x;
this->y = this->C::y;
std::cout << "x = " << this->x << std::endl;
std::cout << "y = " << this->y << std::endl;
}
};
int main() {
D obj;
return 0;
}
How can I solve this?
This is one of the main problems that is solved by using composition over inheritance.
https://en.wikipedia.org/wiki/Composition_over_inheritance
Instead of inheriting from B and C your D object could contain instances of B and C. See the following example:
#include <iostream>
class A {
protected:
int x;
int y;
public:
A() : x(10), y(10) {}
int GetX() {
return x;
}
int GetY() {
return y;
}
};
class B : virtual public A {
public:
B() {this->x = 20; this->y = 20;}
};
class C : virtual public A {
public:
C() {this->x = 30; this->y = 30;}
};
class D {
public:
D() {
std::cout << "x = " << this->b.GetX() << std::endl;
std::cout << "y = " << this->c.GetY() << std::endl;
}
private:
B b;
C c;
};
int main() {
D obj;
return 0;
}

How to make polymorphic field of class in C++? How to use polymorphism correctly in this case?

I have a class
class A
{
BasePtr * ptr;
virtual BasePtr * getPtr() { return ptr; }
virtual void pure() = 0;
}
And I want to derive two classes from it that create its own versions of ptr:
class B : public A
{
B() : A() { ptr = new RoundPtr(); }
};
class C : public A
{
C() : A() { ptr = new SquarePtr(); }
}
Then I create a list of pointers to basic class:
A * list[2];
list[0] = new B();
list[1] = new C();
And call this method:
list[i]->getPtr();
But I found that it returns an uninitialized pointer.
So, how to correctly use polymorphism here? How to properly create this field to use different types of it?
Ok, I tested this code and it works perfectly o_0 But I got crashed in more complex program when try to call method of polymorphic object pointer. Maybe I have an additional errors in my project.
The answer is:
#include <iostream>
class Ptr {
public:
Ptr(int x, int y) : centerX(x), centerY(y) {}
virtual ~Ptr() {}
virtual void foo() = 0;
protected:
int centerX, centerY;
};
class RoundPtr: public Ptr {
public:
RoundPtr(int x, int y, int radius) : Ptr(x, y), circleRadius(radius) {}
virtual void foo() { std::cout << "RoundPtr, x: " << centerX << ", y: " << centerY << ", radius: " << circleRadius << std::endl; }
protected:
int circleRadius;
};
class SquarePtr: public Ptr {
public:
SquarePtr(int x, int y, int w, int h) : Ptr(x, y),
leftX(centerX - w/2), leftY(centerY - h/2),
width(w), height(h)
{}
virtual void foo() { std::cout << "SquarePtr, x: " << centerX << ", y: " << centerY << ", leftX: " << leftX << ", leftY: " << leftY << ", width: " << width << ", height: " << height << std::endl; }
protected:
int leftX, leftY;
int width, height;
};
class A {
protected:
Ptr * ptr;
public:
A() : ptr(nullptr) {}
virtual ~A() {}
virtual Ptr * getPtr() { return ptr; }
};
class B : public A {
public:
B() : A() { ptr = new RoundPtr(0, 0, 10); }
virtual ~B() { delete ptr; }
};
class C : public A {
public:
C() : A() { ptr = new SquarePtr(5, 5, 10, 10); }
virtual ~C() { delete ptr; };
};
int main()
{
A * bObj = new B();
A * cObj = new C();
bObj->getPtr()->foo();
cObj->getPtr()->foo();
delete bObj;
delete cObj;
}
Can anybody check this code? Do you see any problems with it? Is it good solution? Is it possible to use smart pointers from c++11 here?

C++ Derived classes won't work without default parameters, even then wrong

Suppose I have a base class A, two derived classes B and C which are virtual public A, and a final class D, which is public B, public C. I tried to make a working code for this:
#include <iostream>
class A
{
protected:
int m_x;
public:
A(int a): m_x {2 * a} { std::cout << "A()" << '\n'; }
};
class B : virtual public A
{
private:
int m_y, m_z;
public:
B(int a): m_y {a * a}
{
m_z = 2 * m_y + 1;
A(m_z);
std::cout << "B()" << '\n';
}
int getVal() { return m_y; }
};
class C : virtual public A
{
private:
int m_p, m_q;
public:
C(int a): m_p {1 - a}
{
m_q = m_p - 3 * a;
A(m_q);
std::cout << "C()" << '\n';
}
int getVal() { return m_p; }
};
class D : public B, public C
{
private:
int m_w;
public:
D(int a, int b)
{
switch (b)
{
case 1: { B(a); break; }
case 2: { C(a); break; }
}
m_w = m_x * a;
std::cout << "D()" << '\n';
}
int getVal() { return m_z; }
};
int main(int argc, char *argv[])
{
D d {5, 1};
std::cout << d.getVal() << '\n';
return 0;
}
All classes normally have their own .h and .cpp file, I compacted it a bit and the formulas are pure fiction. The short story is that A acts as an interface class who has m_x as a common variable for both B and C, to be used and modified as needed, while D uses A's variable to further calculate the desired m_w. The two virtual classes are called on a need basis, from D.
My problem: I can't compile the above if no default parameters are given, but if they are, the results are wrong.
a) As it is (no default parameters), first error line:
16:29 no matching function for call to A::A()
b) No default parameters, change line 19 to A::A(m_z):
cannot call constructor ‘B::A’ directly [-fpermissive]
(I think this makes sense, no such thing as B::A)
c) With default parameters: A=2, B=3, C=4, outputs:
A()
A()
B()
A()
C()
A()
A()
B()
D()
10
which looks awful enough (I don't know why so many calls), but it should also be:
B(5) =>
m_y = 5 * 5 = 25
m_z = 2 * 25 + 1 = 51
A(51) =>
m_x = 2 * 51 = 102
finally:
m_w = 102 * 5 = 510
...shouldn't it? Can someone please tell me what I am doing wrong?
You need to call base class constructors in the initializer list, not in the constructor body.
Replace
B(int a): m_y {a * a}
{
m_z = 2 * m_y + 1;
A(m_z);
std::cout << "B()" << '\n';
}
By
B(int a): A(2 * a * a + 1), m_y {a * a}
{
m_z = 2 * m_y + 1;
std::cout << "B()" << '\n';
}
And so on.
In class D you need to call constructors for A, B and C, since C++ doesn't allow second guessing, whether the A constructor would be called from B or C when D is created.
Take 2
Since you actually want D to conditionally construct an instance of B or C, you need to reorganize your design.
Suppose I have temperature readings (A) from different countries (B,
C, etc), and I have to filter/present/display them on
screen/graph/somehow (D) (just an example).
So you have different measurement units of temperatures and you want to display them together in the same measurement unit. For my personal convenience, I say that the target unit is °C.
Lets design a temperature class and some helpers and factory methods
int CelsiusToFahrenheit(int c)
{ return /* somehow calculate F from c */; }
int FahrenheitToCelsius(int f)
{ return /* somehow calculate °C from f */; }
class Temperature
{
protected:
int m_temperatureCelsius;
public:
Temperature(int temperatureCelsius): m_temperatureCelsius { temperatureCelsius }
{ std::cout << "A()" << '\n'; }
int GetCelsius()
{ return m_temperatureCelsius; }
int GetFahrenheit()
{ return CelsiusToFahrenheit(m_temperatureCelsius); }
};
Temperature* CreateTemperatureFromCelsius(int c)
{ return new Temperature(c); }
Temperature* CreateTemperatureFromFahrenheit(int f)
{ return new Temperature(FahrenheitToCelsius(f)); }
Now if you have different countries and want to register a temperature per country item, you could define countries as follows (note: there are MANY other ways)
class BaseCountry
{
protected:
Temperature* m_temperature;
public:
BaseCountry()
{ }
virtual ~BaseCountry() = 0; // abstract class
int GetCountryTemperatureCelsius()
{ return m_temperature ? m_temperature->GetCelsius() : 0; }
}
class CountryA : public BaseCountry
{
public:
CountryA(int temperatureC)
{ m_temperature = CreateTemperatureFromCelsius(temperatureC); }
~CountryA()
{ delete m_temperature; }
}
class CountryB : public BaseCountry
{
public:
CountryB(int temperatureF)
{ m_temperature = CreateTemperatureFromFahrenheit(temperatureF); }
~CountryB()
{ delete m_temperature; }
}
int main(int argc, char *argv[])
{
BaseCountry& c1 = CountryA(10);
BaseCountry& c2 = CountryB(10);
// display 10
std::cout << c1.GetCountryTemperatureCelsius() << '\n';
// display the number in °C for 10 F
std::cout << c2.GetCountryTemperatureCelsius() << '\n';
return 0;
}
In a display/screen/diagram class, you can hold an array of CountryBase references and access their temperature normalized to °C, no matter how they where constructed.

c++ error: object of abstract class type "..." is not allowed

I want to use polymorphism in my program but don't know why when I create
virtual void setVertices()=0;
in class CFigure i get an error
C2259: 'CRectangle': cannot instantiate abstract class (line 63 and 74)
IntelliSense: object of abstract class type "CRectangle" is not allowed:
pure virtual function "CFigure:setVertices" has no overrider (line 63 and 74)
I want also to declare:
virtual void setVertices(CFigure& fig) = 0;
I don't know at all that if I can write CFigure& fig cuz CRectangle i have:
void setVertices(CRectangle& fig)
and those two methods have different parameters.
Can someone can tell me how to help me to explain those errors and tell me how to fix my program? Code:
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
class Point2D{
int x, y;
public:
void setX(int X){ x = X; }
void setY(int Y){ y = Y; }
int getX(){ return x; }
int getY(){ return y; }
};
class CFigure :public Point2D
{
protected:
Point2D Vert[4];
public:
CFigure(){}
//virtual void setVertices(CFigure& fig) = 0;
virtual void setVertices()=0;// if I comment this line all works good
};
class CRectangle : public CFigure
{
public:
CRectangle(){}
void setVertices(CRectangle& fig)
{
//CRectangle fig;
int x1, y1, a;
cout << "Give x1, y1" << endl;
cin >> x1 >> y1;
cout << "Give a" << endl;
cin >> a;
fig.Vert[0].setX(x1);
fig.Vert[0].setY(y1);
fig.Vert[1].setX(x1 + a);
fig.Vert[1].setY(y1);
fig.Vert[2].setX(x1);
fig.Vert[2].setY(y1 + a);
fig.Vert[3].setX(x1 + a);
fig.Vert[3].setY(y1 + a);
}
void showPoints()
{
CRectangle f;
setVertices(f);
for (int i = 0; i < 4; i++)
{
cout << "P" << i << "( " << f.Vert[i].getX() << " " << f.Vert[i].getY() << " ) " << endl;
}
}
};
int main()
{
CRectangle ag;
ag.showPoints();
return 0;
}
CFigure declares setVertices() as:
virtual void setVertices()=0;
But CRectangle declares setVertices() as:
void setVertices(CRectangle& fig)
The additional parameter makes it so CRectangle::setVertices() is not overriding CFigure::setVertices(). It is overloading it instead. That is why the compiler is complaining that CRectangle is an abstract class - it really is. When you override a virtual method, the signature of the overriding method must exactly match the signature of the method that is being overridden, eg:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
class Point2D
{
int x, y;
public:
void setX(int X){ x = X; }
void setY(int Y){ y = Y; }
int getX(){ return x; }
int getY(){ return y; }
};
class CFigure : public Point2D
{
protected:
Point2D Vert[4];
public:
CFigure() {}
virtual void setVertices()=0;
};
class CRectangle : public CFigure
{
public:
CRectangle() {}
void setVertices()
{
int x1, y1, a;
cout << "Give x1, y1" << endl;
cin >> x1 >> y1;
cout << "Give a" << endl;
cin >> a;
Vert[0].setX(x1);
Vert[0].setY(y1);
Vert[1].setX(x1 + a);
Vert[1].setY(y1);
Vert[2].setX(x1);
Vert[2].setY(y1 + a);
Vert[3].setX(x1 + a);
Vert[3].setY(y1 + a);
}
void showPoints()
{
setVertices();
for (int i = 0; i < 4; i++)
{
cout << "P" << i << "( " << Vert[i].getX() << " " << Vert[i].getY() << " ) " << endl;
}
}
};
int main()
{
CRectangle ag;
ag.showPoints();
return 0;
}

in base class, how to define a container to contain function obj which can be any func of derived class?

I want to define a container in the base class, which contains function obj or anything that can make my purpose happen. These function obj can call derived classes' functions. they all take same parameters.
#include <vector>
#include <functional>
#include <iostream>
class Foo {
Foo() {}
virtual ~Foo(){}
virtual void init()
{ registerCallback(0, &Foo::print_ori ); }
void print_ori(int i) const { std::cout << i << '\n'; }
void registerCallback(int key, ??? cb ) // NOT SURE HOW TO DEFINE THIS
{
callbacks[key] = cb;
}
void runCallbacks(int key, int n)
{
auto i = callbacks.find(key);
if (i != callbacks.end()) {
(*i)(*this, n);
}
}
std::map<int, std::function<void(const Foo&, int) > > callbacks; // obviously, it's wrong. how to fix it?
};
struct Foo2 : public Foo {
Foo2(int num) : Foo(num) {}
virtual void init()
{
Foo::init();
registerCallback(11, &Foo2::print1 );
registerCallback(12, &Foo2::print2 );
}
void print1(int i) const { std::cout << " - Foo2.p1 - " << i << endl; }
void print2(int i) const { std::cout << " - Foo2.p2 - " << i << endl; }
};
int main()
{
Foo* obj = new Foo2();
obj->init();
obj->runCallbacks(12, 456);
}
Here's a way to achieve what your code looks like it's trying to do, without using function pointers:
class Foo {
Foo() {}
virtual ~Foo(){}
void print_ori(int i) const { std::cout << i << '\n'; }
virtual void do_runCallbacks(int v)
{
}
void runCallbacks()
{
print_ori(3)
do_runCallBacks(3);
}
};
struct Foo2 : public Foo {
Foo2(int num) : Foo(num) {}
void do_runcallbacks(int v)
{
print1(v);
print2(v);
}
void print1(int i) const { std::cout << " - Foo2.p1 - " << i << endl; }
void print2(int i) const { std::cout << " - Foo2.p2 - " << i << endl; }
};
int main()
{
Foo* obj = new Foo2();
obj->runCallbacks();
}
Now, there may well be reasons to do this completely differently, but I don't see why you should need both virtual functions and inheritance, AND function objects/function pointers. That seems quite wrong to me ("smells bad")
Edit:
Here's something I came up with, that solves the type of problem you describe after edits of the original question.
#include <iostream>
#include <map>
using namespace std;
class event_interface
{
public:
virtual void action(int n) = 0;
};
class event_manager
{
public:
event_manager(int n) : num(n) {}
void register_event(int key, event_interface *eh)
{
handlers[key] = eh;
}
void callback(int key)
{
auto h = handlers.find(key);
if (h != handlers.end())
{
h->second->action(num);
}
}
private:
map<int, event_interface *> handlers;
int num;
};
class handler1 : public event_interface
{
public:
void action(int n) { cout << "in handler1::action. n=" << n << endl; }
};
class handler2 : public event_interface
{
public:
handler2(int n) : data(n) {}
void action(int n)
{
cout << "in handler2::action. n=" << n
<< " data = " << data << endl;
}
private:
int data;
};
class multihandler
{
private:
class handler3: public event_interface
{
public:
void action(int n) { cout << "in handler3::action. n=" << n << endl; }
};
class handler4: public event_interface
{
public:
handler4(multihandler *m) : mh(m) {}
void action(int n)
{
cout << "in handler4::action. n=" << n
<< " data = " << mh->data << endl;
}
private:
multihandler* mh;
};
public:
multihandler(event_manager& em) : h4(this)
{
em.register_event(62, &h3);
em.register_event(63, &h4);
data = 42;
}
private:
handler3 h3;
handler4 h4;
int data;
};
int main()
{
event_manager mgr(3);
handler1 h1;
handler2 h2(77);
multihandler mh(mgr);
mgr.register_event(12, &h1);
mgr.register_event(13, &h2);
int evts[] = { 12, 63, 62, 13, 18 };
for(auto i : evts)
{
cout << "Event: " << i << endl;
mgr.callback(i);
}
}