Derive Smiley from Circle - c++

I am trying to derive class Smiley from Circle:
struct Smiley : Circle {
void draw_lines() const;
};
void Smiley::draw_lines() const {
Circle::draw_lines(); // outline
/*rest of code here*/
}
This is the definition of Circle:
struct Circle : Shape {
Circle(Point p, int rr); // center and radius
void draw_lines() const;
Point center() const;
void set_radius(int rr) { set_point(0, Point(center().x - rr, center().y - rr)); r = rr; }
int radius() const { return r; }
private:
int r;
};
I basically want a Circle with a couple arcs drawn on top. Theoretically, I should only have to write draw_lines() over (which is defined as virtual in Shape), but it does nothing without a constructor, and if I have a constructor, it get an error and says that Circle does not have a default constructor available, even if I have no code in the constructor relating to Circle.
Does anyone know why I am getting this error?

When you inherit from a class with no default constructor, you have to make sure you invoke the non-default one.
Otherwise your derived class tries to invoke that non-existent default constructor, as the error says. In this case, you can probably just pass the same arguments straight through.
struct Smiley : Circle {
Smiley(Point p, int rr);
void draw_lines() const;
};
Smiley::Smiley(Point p, int rr)
: Circle(p, rr)
{};
I basically want a Circle with a couple arcs drawn on top
Then it's not a circle any more, so why does Smiley inherit Circle?

You've defined a constructor for circle that requires a Point and a Radius. You should define one with identical parameters for Smiley, that invokes the base class constructor with those parameters, via a Member Initialiser List.
struct Smiley : Circle {
Smiley(Point p, int rr) : Circle(p, rr)
{
}
void draw_lines() const;
};

Related

Why does the base constructor get called instead of the one with parameters (virtual inheritance)? [duplicate]

This question already has answers here:
Calling a virtual base class's overloaded constructor
(4 answers)
Closed 11 months ago.
#include <iostream>
using namespace std;
class Point
{
int x,y;
public:
Point()
{
x=0;
y=0;
}
Point(int x, int y)
{
this->x=x;
this->y=y;
}
Point(Point &p)
{
x=p.x;
y=p.x;
}
friend class Square;
};
class Square
{
Point _point;
int side;
public:
Square() {cout<<"Square.\n";}
Square(Point &p, int side_val): _point(p), side(side_val)
{
cout<<"Square constructor that should be used.\n";
}
};
class Rectangle: public virtual Square
{
int side2;
public:
Rectangle() {}
Rectangle(Point &p, int side_1, int side_2): Square(p,side_1), side2(side_2) {}
};
class Rhombus: public virtual Square
{
Point opposite_point;
public:
Rhombus() {cout<<"Rhombus. \n";}
Rhombus(Point &p, Point &q, int side_1): Square(p, side_1), opposite_point(q)
{
cout<<"Rhombus constructor that should be used \n";
}
};
class Paralellogram: public Rectangle, public Rhombus
{
public:
Paralellogram(Point &p, Point &q, int side_1, int side_2): Rhombus(p,q,side_1),Rectangle(p,side_1,side_2)
{
cout<<"Parallelogram constructor that should be used\n";
}
};
int main()
{
Point down_left(3,5);
Point up_right(2,6);
int side_1=5;
int side_2=7;
Paralellogram par(down_left,up_right,side_1,side_2);
}
The output I get is:
Square
Rhombus constructor that should be used
Paralellogram constructor that should be used
And what I'm trying to do is instantiate a Paralellogram that has combined variables from a Rhombus and a Rectangle (it should have a _point, opposite_point, side, side2) and I don't want them to double up hence I'm using virtual inheritance. But the constructor of Square that I intended should be used never gets called, even once, instead the base constructor gets called.
What should I do? Give up on the virtual inheritance?
In virtual inheritance, virtual base is constructed according to the most derived class.
class Paralellogram: public Rectangle, public Rhombus
{
public:
Paralellogram(Point &p, Point &q, int side_1, int side_2) :
Square(), // You have implicitly that
Rectangle(p,side_1,side_2),
Rhombus(p,q,side_1)
{
cout<<"Parallelogram constructor that should be used\n";
}
};
You probably want
class Paralellogram: public Rectangle, public Rhombus
{
public:
Paralellogram(Point &p, Point &q, int side_1, int side_2) :
Square(p, side_1),
Rectangle(p,side_1,side_2),
Rhombus(p,q,side_1)
{
cout<<"Parallelogram constructor that should be used\n";
}
};
As explained in Understanding virtual base classes and constructor calls:
There is always just one constructor call, and always of the actual, concrete class that you instantiate. It is your responsibility to endow each derived class with a constructor which calls the base classes' constructors if and as necessary, as you did in [Rectangle and Rhombus]'s constructor[s].
Ask yourself: what if the Rectangle and Rhombus calls disagreed on how the unique (since virtual) instance of Square should be initialized ? Who should we listen to ? The answer is neither. It's always the responsibility of the current class, here Parallelogram, to initialize the virtual bases. And since here no constructor is specified, it is considered that Parallelogram calls the default constructor of Square.

Why can't I declare a data member from another class private within my class definition

I am getting a compiler error saying that the data member Point p is private within the context, when I declare Point p as private within class circle. The code and compiler error are below.
#include<iostream>
#include<vector>
class Point
{
public:
Point(double a, double b)
{
x = a;
y = b;
}
virtual ~Point(){}
private:
double x;
double y;
};
The code for the class shape and circle are as follows:
class shapes {
public:
virtual Point centre() const = 0;
virtual void draw() const = 0;
virtual void rotate(int angle) const = 0;
virtual ~shapes(){}
};
class circle: public shapes {
public:
Point centre() const override { return p; }
void draw() const override { }
void rotate(int angle) const override {}
virtual ~circle() {}
circle(Point x, int r):p{x},radius{r}{}
private:
Point p;
int radius; };
Edit: Smiley face class inherits from circle class with code below:
class smiley: public circle
{ //smiley face is a circle + eyes and mouth
public:
smiley(Point p, int r):circle{p,r},mouth{nullptr}{}
Point centre() const override { return p;}
void draw() const override
{
//draw circle
circle::draw();
for(auto e:eyes)
{
e->draw();
}
mouth->draw();
}
void rotate(int angle) const {}
virtual ~smiley()
{
delete mouth;
for (auto eye : eyes) //why not delete [] eyes
{
delete eye;
}
}
private:
std::vector<shapes*> eyes; //smiley face has eyes
shapes* mouth; //smiley face has a mouth
};
If I make the data member p public in the class circle, everything works. The compiler error is listed below:
Why can I not define the Point object p, in the circle class private?
Edit: I have added the compiler error message and added the missing code asked for in the comments below. Would you be able to re-open the question?
Private class members can only be accessed within the class or by friends, so, if you would like it to be accessed outside the class by a non-friend, you would need to use a setter/getter.

C++ derived class unable to access protected members, unless default constructor is used

Initializing fields within constructor works:
class Shape{
protected:
float width,height;
public:
Shape()
{
width = 13.2;
height = 3.2;
}
}
However when using a constructor with parameters, the code no longer compiles:
class Shape{
protected:
float width,height;
public:
Shape(float w, float h)
{
width = w;
height = h;
}
}
Triangle class:
class Triangle : public Shape{
public:
float area()
{
return (width * height / 2);
}
Here is the main function:
int main() {
Shape s = Shape();
Triangle tri;
std::cout << tri.area() << std::endl;
return 0;
This compiles and outputs result:
21.12
However when using constructor with parameters Shape s = Shape(13.2,3.2);
it seems the Triangle object tri can no longer access the width and height of Shape class.
The problem is that by defining Shape's constructor with arguments, you disable the default constructor of Shape (or more precisely, define it as deleted). And since Triangle does not define a default constructor, it also gets marked as deleted.
You need to either define the default constructor of Shape, or define a constructor of Triangle that will call the constructor of Shape with parameters w and h.

c++ polymorphism - passing a reference to base class to a function

I'm learning about c++ polymorphism. In the code below, a pointer called shape of the type of the base class Shape is creates and then pointed at the objects r and c.
The functions printArea(r); and printArea(c); are then called. However, at the point that these functions are called shape is pointing to the address of c. So how does it work when you call printArea(r);?
#include<iostream>
using namespace std;
class Shape {
public:
virtual float getArea() const = 0;
};
class Rectangle : public Shape {
private:
float width;
float height;
public:
Rectangle(float width, float height) : width(width), height(height) {}
float getArea() const {return width * height;}
};
class Circle : public Shape {
private:
float radius;
public:
Circle(float radius) : radius(radius) {}
float getArea() const {return 3.14159f * radius *radius;}
};
void printArea(const Shape& shape) {
std::cout << "Area: " << shape.getArea() << std::endl;
}
int main() {
Rectangle r(2,6);
Shape* shape = &r;
Circle c(6);
shape = &c;
printArea(r);
printArea(c);
printArea(*shape);
return 0;
}
I would guess your question is how, technically, is the call to getArea dispatched at run time.
The C++ standard does not prescribe this. It prescribes exactly which implementation must be executed, but not how that is accomplished.
Nearly all extant C++ implementations do that by placing a hidden pointer in each object of class with one or more virtual functions. That hidden pointer points to a table of function pointers, namely pointers to the virtual methods of the class of the object's dynamic type. This is called a vtable. And in general the call is dispatched by checking the object's vtable pointer, and retrieving the function pointer from the getArea item in the vtable, and calling that function.
There are complications for multiple inheritance, but those are just that: complications.
An alternative could be to search up the base class chain for each call.
That would be less efficient but still it's been used, at least in other languages, e.g. in original Smalltalk, and in Borlands GUI class framework for Pascal in Windows in the 1990s.
Another alternative is to place pointers to each virtual function directly in each object, essentially a vtable in each object. That approach is sometimes used in C. The main advantage is that it's conceptually simple. It also avoids one indirection. But it wastes space and doesn't generalize very well.
#include<iostream>
using namespace std;
class Shape {
public:
virtual float getArea() const = 0;
};
class Rectangle : public Shape {
private:
float width;
float height;
public:
Rectangle(float width, float height) : width(width), height(height) {}
float getArea() const {return width * height;}
};
class Circle : public Shape {
private:
float radius;
public:
Circle(float radius) : radius(radius) {}
float getArea() const {return 3.14159f * radius *radius;}
};
void printArea(const Shape& shape) {
std::cout << "Area: " << shape.getArea() << std::endl;
}
int main() {
Rectangle r(2,6);
Shape* shape = &r; // shape stores the address of object r which when further call
std::cout<< shape <<endl; //called sends its address
Circle c(6);
shape = &c; // same as r is being processed
std::cout<<shape<<endl;
printArea(r); // same thing is taking place here reference is passed and then polymorphism come
printArea(c); // into play
printArea(*shape); // as the shape was given reference of c in the end it returns its value
return 0;
}
if u still have any questions feel free to ask in comments!

C++ polygon rectangle and triangle inheritance

I am trying to make a Polygon class and a Rectangle and Triangle that inherit the first. Polygon class has height and width variables that I want them to be be given values within the constructor. Then, Rectangle and Triangle have area calculation methods. Then, I use a main() to give some examples. I use:
#include <iostream>
using namespace std;
class Polygon {
public:
Polygon(int, int);
protected:
int height;
int width;
};
class Rectangle: public Polygon {
public:
void calc_area();
};
class Triangle: public Polygon {
public:
void calc_area();
};
Polygon::Polygon(int a, int b) {
height = a;
width = b;
}
void Rectangle::calc_area() {
cout << "Rectangle area: " << (height*width) << endl;
}
void Triangle::calc_area() {
cout << "Triangle area: " << (height*width/2) << endl;
}
int main() {
Rectangle s1(5, 2);
Triangle s2(5, 2);
s1.calc_area();
s2.calc_area();
}
But while everything looks ok to my newbie eyes, I get a series of errors:
12 base Polygon' with only non-default constructor in class without a constructor `
36 no matching function for call to `Rectangle::Rectangle(int, int)
37 no matching function for call to `Triangle::Triangle(int, int)'
Can someone give me some tips? As seen, I am very new to C++...
You shouldn't call constructor to use ., such as:
Rectangle s1;
Triangle s2;
s1.Polygon(5, 2);
s2.Polygon(5, 2);
try this way:
Rectangle s1(5, 2);
Triangle s2(5, 2);
and you should add constructor for Rectangle and Triangle respectively:
class Rectangle: public Polygon {
public:
Rectangle(int height, int width):Polygon(height, width){}
void calc_area();
};
class Triangle: public Polygon {
public:
Triangle(int height, int width):Polygon(height, width){}
void calc_area();
};
To construct Triangle and Rectangle you are calling their invisible default constructors.
So the Triangle() and Rectangle() methods. These are implemented as empty methods, but they must also call the default constructors of any class they inherit from. So effectively this is the code that's being generated:
Triangle() : Polygon() {}
Rectangle() : Polygon() {}
Polygon will not get a default constructor because you created your own constructor. So the only way to get that back is to define it:
Polygon() {}
Or in C++11:
Polygon() = default;
The default constructor Triangle() or Rectangle() are called when you instantiate the member variable. So these lines are calling constructors:
Rectangle s1;
Triangle s2;
Note that once they are constructed they cannot be reconstructed. So these calls are illegal:
s1.Polygon(5, 2);
s2.Polygon(5, 2);
Now if you want to accomplish having a setting constructor, you can do that, but you'll need to define it for Triangle and Rectangle:
Triangle(int width, int height) : Polygon(width, height) {}
Triangle(int width, int height) : Polygon(width, height) {}
Again recall that defining these methods will cause your default constructor not to be generated for Triangle or Rectangle. So your s1 and s2 declarations will now be illegal, but that's OK cause you want to declare them with your new constructors anyway:
Rectangle s1(5, 2);
Triangle s2(5, 2);
You must use this way...
Rectangle *s1 = new Rectangle;
s1->ab(5,2);
s1->calc_area();