C++ Protected inheritance - c++

ok so i've just encountered some weird problem.
i have the following code:
#pragma once
#include "Point.h"
#include "Shape.h"
class Polygon : public Shape{
public:
Polygon(int = 0);
Point& operator[] (int) const;
protected:
Point *Points;
private:
int Num_Of_Points;
};
Cpp file
Polygon::Polygon(int Num) : Num_Of_Points(Num) { Points = new Point[Num_Of_Points](); }
Point& Polygon::operator[] (int index) const{ return Points[index]; }
2nd header.
#pragma once
#include "Polygon.h"
class Triangle : public Polygon{
Triangle(Point, Point, Point);
private:
double Area;
};
Triangle::Triangle(Point A, Point B, Point C) : Polygon (3) {
Points[0] = A;
Points[1] = B;
Points[2] = C;
}
now i get the following error at Triangle constructor:
Error 1 error C2248: 'Polygon::Points' : cannot access private member declared in class 'Polygon'
i cant understand why, Points is protected member and not private (i get the same error when i put it under public aswell)...
help would be much appriciated!
EDIT: forgot to mention, polygon is abstract class, it inherit from shape some abstract functions.

Related

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.

Correct Syntax for Inheritance in C++ with initialize list and memory allocation?

class shape{
public:
shape(string a, bool b):name(new string), moral(new bool){
*name=a;
*moral=b;
}
shape():name(new string),moral(new bool){
*name="shape";
*moral=true;
}
~shape(){
delete name;
delete moral;
}
protected:
string* name;
bool* moral;
};
class circle:public shape{
public:
circle(string s, bool bb, double d):shape(new string, new
bool),radius(new double){
}
protected:
double * radius;
};
Recently, I was trying to pick up c++. Here is a sample code I wrote when learning the property of inheritance. There are errors show on "shape(new string, new bool)" in child class circle. I am not sure what is right syntax to do that. Also, I noticed if were using pointers in classes, the form of initialize list were used to allocate memory instead of assigning values. Are there better expressions and syntax I can use to do both? Thank you guys in advance.
prefer to deal in values. c++ is not like java or c#. Avoid pointers, new and delete for this kind of thing.
If you don't write a destructor, the compiler gives you correct destructors. copies and moves for free.
#include <string>
class shape{
public:
shape(std::string a, bool b) : name(a), moral(b)
{
}
shape():name("shape"),moral(true){
}
protected:
std::string name;
bool moral;
};
class circle:public shape{
public:
circle(std::string s, bool bb, double d)
: shape(s, bb)
, radius(d)
{
}
protected:
double radius;
};
But in the real class I want to use dynamic memory for storage:
#include <string>
#include <memory>
class shape{
public:
shape(std::string a, bool b)
: name(std::make_unique<std::string>(a))
, moral(b)
{
}
shape()
: shape("shape", true)
{
}
protected:
std::unique_ptr<std::string> name;
bool moral;
};
class circle:public shape{
public:
circle(std::string s, bool bb, double d)
: shape(s, bb)
, radius(d)
{
}
protected:
double radius;
};

Redefinition of Class C++ - Xcode

I searched through some of the other pages with this same error, but my code does not have any of their issues that I can find. It could just be that I am tired and slightly new to C++, if so sorry.
I have a parent class, shape.h, that has three derived classes; rectangle.h, triangle.h, and circle.h. The parent class is the one that gets the error "Redefinition of 'Shape'" on the third line. For the life of me I can not figure out what is wrong, other than possible the way I call the shape constructors from the derived classes. Please help, anymore information you need just let me know.
Shape.h:
#include < cmath>
class Shape
{
public:
//constructors
Shape();
Shape(float a);
Shape(float a, float b);
//Returns
float area();
float perimeter();
protected:
float base;
float height;
float radius;
};
Shape.cpp:
#include "Shape.h"
//constructors
Shape::Shape()
{
base = 0;
height = 0;
radius = 0;
}
Shape::Shape(float a)
{
radius = a;
}
Shape::Shape(float a, float b)
{
base = a;
height = b;
}
//returns
float Shape::area()
{
return 0;
}
float Shape::perimeter()
{
return 0;
}
All derived classes are the same except different calculations , so here is Circle.h:
#include "Shape.h"
class Circle: public Shape
{
public:
//constructors
Circle();
Circle(float a);
//Returns
float area();
float perimeter();
private:
};
Circle.cpp:
#include "Circle.h"
//constructors
Circle::Circle():Shape()
{
}
Circle::Circle(float a):Shape(a)
{
}
//returns
float Circle::area()
{
return (3.14 * pow(radius,2));
}
float Circle::perimeter()
{
return (2 * 3.14 * radius);
}
In Circle.cpp Shape.h indirectly included twice and causes mentioned compilation error.
Add include guard to your headers. E.g. Shape.h should be:
#ifndef SHAPE_H
#define SHAPE_H
// Put your Shape class here
#endif
The other approach is to use #pragma once at the beggining of Shape.h if your compiler supports it.

Class inaccessible pointer

Hello need your help to solve this problem or just explain me why my pointer is inaccessible .
PlayerSprite.h
#pragma once
#include "LoadPlayerRes.h"
#include "Keyboard.h"
#include "PlayerState.h"
class PlayerSprite :public LoadPlayerRes{
public:
PlayerSprite(float x, float y,float speed)
:
x(x),
y(y),
speed(speed)
{
pCurrentState = new StateStand(&Stand);
}
void Controls(Keyboard& kbd) {
speed = 0;
if (speed == 0) {
delete pCurrentState;
pCurrentState = new StateStand(&Stand);
}
}
void Draw(Graphics& gfx) {
pCurrentState->pSprite->Draw(x, y, gfx);// pSprite inaccessible
}
private:
float x, y,speed;
PlayerState* pCurrentState;
};
PlayerState.h
#pragma once
#include "SurfaceAnimation.h"
class PlayerState {
public:
PlayerState(SurfaceAnimation* pSprite)
:
pSprite(pSprite)
{}
protected:
SurfaceAnimation* pSprite;
};
class StateStand :public PlayerState {
public:
StateStand(SurfaceAnimation* pSprite)
:
PlayerState(pSprite)
{}
};
so i am trying to make a player state machine ,PlayerState class job is to point to right SurfaceAnimation object and based on pointer i will draw a player inside PlayerSprite class , but for some reason pSprite is inaccessible.
It's inaccessible because you made it protected.
So, only functions in PlayerState (or functions in classes inheriting PlayerState), can see it.
You're trying to access it from a function in PlayerSprite.

Pure Virtual Function error in factory design pattern

studying for a final and decided to build a program which makes use of pure virtual functions and polymorphism. i am stuck on a really weird error maybe i am missing something.
This is the Shape abstract class
#ifndef Shape_hpp
#define Shape_hpp
#include <stdio.h>
#include <string.h>
class Shape{
const char* name;
public:
Shape(const char* abc);
virtual double getPerimeter()=0;
virtual double getArea()=0;
};
#endif /* Shape_hpp */
The Shape .cpp implementation file
#include "Shape.hpp"
Shape::Shape(const char *shape){
name = shape;
}
The Circle Header file
#ifndef Circle_hpp
#define Circle_hpp
#include "Shape.hpp"
#include <stdio.h>
class Circle:public Shape{
double m_radius;
public:
Circle(double rad);
double getRadius();
};
#endif /* Circle_hpp */
The circle .cpp implementation file
#include "Circle.hpp"
#include "Shape.hpp"
Circle::Circle(double rad):Shape("Circle"){
m_radius = rad;
}
double Circle::getRadius(){
return m_radius;
}
double Circle::getPerimeter(){
return (2 * 3.14 * m_radius);
}
double getArea(){
return 0;
}
I declared the two pure virtual functions in the abstract "shape" class and am accessing the public of shape class in circle header file, if i declare the pure virtual functions in the circle class it will make it abstract... the error says "Out-of-line definition of 'getPerimeter' does not match any declaration in 'Circle'"
Am i missing something or am i thinking about this the wrong way..
Help would be appreciated. Thanks!
You need to declare all member functions that you define. So in class Circle you need to add:
virtual double getPerimeter();
Or better in C++11:
double getPerimeter() override;
You're defining Circle::getPerimeter() in your .cpp file but there is no member function getPerimeter() in the Circle class declaration. All pure virtual functions need to be overriden in a derived class in order for the class to become concrete. So yes, virtual double getPerimeter(); and override if you're using C++11.
Also, it's good practice to declare simple getters const.
It should be done this way.
class Shape{
const char* name;
public:
Shape(const char* abc);
virtual ~Shape() {} // you should have virtual destructor here
virtual double getPerimeter()=0;
virtual double getArea()=0;
};
class Circle:public Shape{
double m_radius;
public:
Circle(double rad);
double getRadius();
virtual double getPerimeter(); // we need to re-declare it here
virtual double getArea(); // we need to re-declare it here
};
Here's a suggestion. Since Shape is an abstract class, we cannot create objects of the class; so get rid of its constructor. Since we are interested in area and parameter of shapes, define the functions as virtual.
So, here is a redeclaration of Shape class.
#ifndef __SHAPE__
#define __SHAPE__
namespace shape
{
class Shape
{
public:
virtual float getArea()=0;
virtual float getPerimeter()=0;
};
}
#endif
Now, redeclaration of Circle class
#ifndef __CIRCLE__
#define __CIRCLE__
#include "inc/Shape.hpp"
namespace shape
{
class Circle: public Shape
{
float radius;
public:
Circle(float=0.0);
float getArea();
float getPerimeter();
};
}
#endif
Now redefining Circle class
#include "inc/Circle.hpp"
namespace shape
{
Circle::Circle(float radius)
{
this->radius = radius;
}
float Circle::getArea()
{
return ((22/7) * (this->radius * this->radius));
}
float Circle::getPerimeter()
{
return (2 * (22/7) * this->radius);
}
}
Now, in the main class
#include <iostream>
#include "inc/Circle.hpp"
int main()
{
shape::Shape *circle = new shape::Circle(2.5);
std::cout << "Area: " << circle->getArea() << std::endl;
std::cout << "Perimeter: " << circle->getPerimeter() << std::endl;
return 0;
}
You may redeclare the classes without namespaces.
The point to note is that the type of object created should be of the parent class and the object itself should be a child class.
One last thing; all pure virtual functions in the abstract must be redeclared and redefined (overridden) in the derived classes.