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

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;
}

Related

c++ base class and derived class example

Haha, so I'm a little late to starting my homework and would enjoy having someone explain this to me, I read parts of my textbook so I understand the simple examples of base classes and derived classes but other than that I'm stumped. It doesn't seem to hard but I just need some help on where to start/look.
What is the output of the following C++ program? 
#include <iostream>
#include <string>
using namespace std;
class baseClass {
public:
void print() const;
baseClass(string s = " ", int a = 0);
// Postcondition: str = s; x = a;
protected:
int x;
private:
string str;
};
class derivedClass : public baseClass {
public:
void print() const;
derivedClass(string s = "", int a = 0, int b = 0);
};
// Postcondition: str = s; x = a; y = b;private:int y;};
int main() {
baseClass baseObject("This is the base class", 2);
derivedClass derivedObject("DDDDDD", 3, 7);
baseObject.print();
derivedObject.print();
system("pause");
return 0;
}
void baseClass::print() const { cout << x << " " << str << endl; }
baseClass::baseClass(string s, int a) {
str = s;
x = a;
}
void derivedClass::print() const {
cout << "Derived class: " << y << endl;
baseClass::print();
}
derivedClass::derivedClass(string s, int a, int b)
: baseClass("Hello Base", a + b) {
y = b;
}
I haven't tried anything yet lol, just started my homework too late and it is due today and would love a quick explanation and help with the answer.

Destructor called two times in 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.

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;
}