I am having trouble with my circle constructor which is inherited from the Point2D class.
shape.h:
#pragma once
class Shape {
public:
virtual float area() const = 0;
virtual float circumference() const = 0;
};
Point2D.h:
#pragma once
#include "Shape.h"
template<class T>
class Point2D : public Shape {
protected:
T x, y;
public:
Point2D() : x(0), y(0) { }
Point2D(T x, T y) : x(x), y(y) { }
T getX() const;
T getY() const;
void setX(T x);
void setY(T y);
};
template<class T>
T Point2D<T>::getX() const {
return x;
}
template<class T>
T Point2D<T>::getY() const {
return y;
}
template<class T>
void Point2D<T>::setX(T x) {
Point2D<T>::x = x;
}
template<class T>
void Point2D<T>::setY(T y) {
Point2D<T>::y = y;
}
Circle.h:
#pragma once
#include "Point2D.h"
#include "CustomException.h"
template<class T>
class Circle: public Point2D<T> {
protected:
T x, y, radius;
public:
Circle() : x(0), y(0), radius(0){}
Circle(T x, T y, T radius) : Point2D<T>(x,y), radius(radius) { }
T getRadius() const;
void setRadius(T radius);
virtual float area();
virtual float circumference();
};
template<class T>
T Circle<T>::getRadius() const {
return radius;
}
template<class T>
void Circle<T>::setRadius(T radius) {
Circle<T>::radius = radius;
}
template<class T>
float Circle<T>::area() {
return 3.14*radius*radius;
}
template<class T>
float Circle<T>::circumference() {
return 3.14*2*radius;
}
I get these errors:
error: invalid new-expression of abstract class type ‘Circle<int>’
Circle<int> *circleInt = new Circle<int>(2, 2, 4);
because the following virtual functions are pure within ‘Circle<int>’:
class Circle: public Point2D<T> {
virtual float Shape::area() const
virtual float area() const = 0;
virtual float Shape::circumference() const
virtual float circumference() const = 0;
Why am I getting these errors? How can I fix this?
Just got it! Since I need to override the virtual method area() and circumference() from shape.h, the method of area() and circumference() need to change. And they always need to change to constant method.
virtual float area(); >>>>>> float area() const override;
virtual float circumference; >>>>>> float area() const override;
Related
I have one Base and many (1..N) Derived classes like that:
class Base {
public:
virtual void OnMouseMove(int x, int y) = 0;
}
class Derived_1: public Base {
public:
void OnMouseMove(int x, int y) override;
}
class Derived_2: public Base {
public:
void OnMouseMove(int x, int y) override;
}
void Derived_1::OnMouseMove(int x, int y) {actions 1};
void Derived_2::OnMouseMove(int x, int y) {actions 2};
All derived classes have the same definition but different OnMouseMove() functions.
I do not like how the program looks, because I have to write in header files all the same derived functions only with different names Derived_1, Derived_2.
Is it possible to write program shorter? I need something like that:
class Derived: public Base {
public:
void OnMouseMove(int x, int y) override;
}
class Derived_1 : public Derived{};
class Derived_2 : public Derived{};
void Derived_1::OnMouseMove(int x, int y) {actions 1};
void Derived_2::OnMouseMove(int x, int y) {actions 1};
What about using templates in that case like this one:
class Base {
public:
virtual void OnMouseMove(int x, int y) = 0;
};
template < int N>
class Derived: public Base {
public:
void OnMouseMove(int x, int y) override;
};
template<> void Derived<1>::OnMouseMove(int x, int y) {std::cout<< "1"<< std::endl;}
template<> void Derived<2>::OnMouseMove(int x, int y) {std::cout<< "2"<< std::endl;}
int main()
{
Base* ptr1 = new Derived<1>;
Base* ptr2 = new Derived<2>;
ptr1->OnMouseMove(5,6);
ptr2->OnMouseMove(5,6);
}
I am trying to make all my classes to be generic.But the issue arose with class Circle and the ones following right after it.Where am I making a mistake?
It seems to work when I exchange them for "int". But that seems to fail my original needs of having the classes be generic.
class DrawableObject
{
public:
virtual void print()=0;
};
template <typename T>
class Point : public DrawableObject
{
T x;T y;
public:
Point()
{ x=0;
y=0;
}
Point(T a)
{ x=a;
y=a;
}
Point(T a,T b)
{ x=a;
y=b;
}
void setX(T newX)
{
x=newX;
}
void setY(T newY)
{
y=newY;
}
T getX()
{ return x;
}
T getY()
{ return y;}
void print()
{ cout<<"(X,Y) Coordinates are ("<<x<<","<<y<<")"<<endl;}
};
template <typename U>
class Rectangle : public Point<U>
{
U width,height;
public:
Rectangle()
{ width=0;
height=0;
}
Rectangle(U a)
{ width=a;
height=a;
}
Rectangle(U a,U b)
{ width=a;
height=b;
}
void setWidth(U newWidth)
{ width=newWidth;}
void setHeight(U newHeight)
{ height=newHeight;}
U getHeight()
{ return height;}
U getWidth()
{ return width;}
void print()
{ cout<<"Rectangle is of area "<<width<<"X"<<height<<endl;}
};
Issue arises from here onwards
template <typename V>
class Circle : public Point<V>
{
V radius;
public:
Circle():Point()
{
radius=0;
}
Circle(V a):Point(a)
{
radius=a;
}
Circle(V a,V b,V c):Point(a,b)
{
radius=c;
}
void setRadius(V newRadius)
{radius=newRadius;}
V getRadius()
{return radius;}
void print()
{cout<<"Circle with centre at ("<<getX()<<","<<getY()<<") and of radius "<<radius<<endl;}
};
Error appears like this one below.
oops_case_study.cpp: In constructor ‘Circle<V>::Circle()’:
oops_case_study.cpp:81:12: error: class ‘Circle<V>’ does not have any field named ‘Point’
Circle():Point()
^~~~~
When you call the base class constructor from the derived constructor you also need to specify the template parameter for the bases class, like below.
Circle() : Point<V>()
{
radius=0;
}
note that Point's constructor is called like Point<V>()
I have this HW question that I have been stuck for hours on that I can't seem to make sense of. It's kind of hard to put to words my actual question but I will try my best. How can I make my outside-member function find the distance between a circle using a class which references another class? In my code below:
//Header
class Point
{
public:
Point();
Point(int, int);
Point(const Point& object);
int getX() const;
int getY() const;
void setX(int);
void setY(int);
double calculate_area();
void print() const;
private:
int x;
int y;
};
class Shape
{
public:
Shape();
double calculate_area();
void print() const;
protected:
double area;
};
class Circle : public Shape
{
public:
Circle();
Circle(const Point&, double);
double getRadius() const;
void setRadius(double);
void calculate_area();
void print() const;
private:
double radius;
Point center;
};
class RTriangle : public Shape
{
public:
RTriangle();
RTriangle(double, double);
double hyp();
void calculate_area();
void print() const;
private:
double side1;
double side2;
};
inline double distance(Circle& other)
{
return sqrt(pow(other.center.x, 2) + pow(other.center.y, 2));
}
#endif
//Implementation.cpp of what i think is important for you guys to see
Point::Point(int inX, int inY) // normal constructor
{
x = inX;
y = inY;
}
Point::Point(const Point &object) // copy constructor needed to use for center of circle
{
x = object.x;
y = object.y;
}
Circle::Circle(const Point& object, double inRad) // center is x & y... radius for circle
{
center = object;
radius = inRad;
}
My outside member function (inline double distance) isn't working. This is the first time I have tried doing this so I apologize if I do not word it well. I am essentially trying to use only the Circle class which inherits point center and point center is defined in the first class as x and y. Is it possible to do such a thing (specifically use x and y which is inside Point center)? I don't know if it's possible to access x and y through center.
Given a Point, functions not in Point can access its x and y members with the public getX() and getY() methods in your example.
However, Circle's center member is not public and has no public accessors. The most straightforward fix would add a public method
Point getCenter(); // or Point const &getCenter() if you like)
to Circle.
Someone recommended me to use boost::variant as shape variable to store different types of shapes in it. But, when implemented boost::variant to my code, I got an error while compiling. Error says: 'Shape': base class undefined and more errors.
Here is my code (Object.h):
using Shape = boost::variant<Rectangle, Circle>;
enum Shape_Type
{
RECTANGLE,
CIRCLE
};
struct Position
{
float x, y;
Position(float position_x, float position_y)
{
x = position_x;
y = position_y;
}
};
class Object : private Shape
{
private:
std::string name;
public:
Object() = default;
Object(std::string name, Rectangle rectangle) : name(name), Shape(rectangle)
{
}
Object(std::string name, Circle circle) : name(name), Shape(circle)
{
}
void setPosition(float, float);
void setAngle(float);
Shape* getShape()
{
Shape* shape = this;
return shape;
}
Position getPosition();
const std::string* getName()
{
return &name;
}
};
class Rectangle
{
private:
sf::RectangleShape rectangleshape;
public:
Rectangle() = default;
Rectangle(float width, float height)
: rectangleshape(sf::RectangleShape(sf::Vector2f(width, height)))
{
}
void setPosition(float position_x, float position_y)
{
rectangleshape.setPosition(position_x, position_y);
}
void setAngle(float angle)
{
rectangleshape.setRotation(angle);
}
sf::RectangleShape* getRectangleShape()
{
return &rectangleshape;
}
Position getPosition()
{
return Position(rectangleshape.getPosition().x,
rectangleshape.getPosition().y);
}
};
class Circle
{
private:
sf::CircleShape circleshape;
public:
Circle() = default;
Circle(std::string name, float radius)
: circleshape(sf::CircleShape(radius))
{
}
void setPosition(float position_x, float position_y)
{
circleshape.setPosition(position_x, position_y);
}
void setAngle(float angle)
{
circleshape.setRotation(angle);
}
sf::CircleShape* getCircleShape()
{
return &circleshape;
}
Position getPosition()
{
return Position(circleshape.getPosition().x,
circleshape.getPosition().y);
}
};
And btw is getShape() function good?
Variants are used for static polymorphism, so you don't need the base class at all (that's dynamic - or virtual - polymorphism).
The members in a variant typically do not share a common base class, so you wouldn't have the getShape function, or you'd need to template it:
template <typename T>
T const& getShape() const { return boost::get<T>(_shape); }
I have two classes with same interface methods:
struct ImplGenerated {
int foo(int x, int y);
void bar(double x);
....
};
struct ImplCustom {
int foo(int x, int y);
void bar(double x);
.....
};
And class Wrapper:
struct Wrapper {
Wrapper(ImplGenerated * i): m_generated(i), m_custom(0) {}
Wrapper(ImplCustom * i): m_generated(0), m_custom(i) {}
int foo(int x, int y);
void bar(double x);
....
private:
??? getImpl();
ImplGenerated * m_generated;
ImplCustom * m_custom;
};
int Wrapper::foo(int x, int y) {
return getImpl()->foo(x, y);
}
void Wrapper::bar(double x) {
getImpl()->bar(x);
}
Is it possible to write some C++ construction (class or any other, but not macros) instead getImpl() for resolving current implementation object and call corresponding method?
like this:
???? getImpl() {
return m_custom ? m_custom : m_generated;
}
Note:
Only changes to ImplCustom could be applied (add base class or make template or something else), ImplGenerated is auto-generated by external project therefore couldn't be changed (add base class is impossible).
Wrapper could not be template, because is interface class.
Update:
It is impossible to derive ImplCustom from ImplGenerated.
The solution I see here is to create a wrapper
The goal of this solution is to generate an interface for your two unrelated classes.
Let's start by making a Base classe:
struct ImplInterface {
virtual int foo(int x, int y) = 0;
virtual void bar(double x) = 0;
// ...
};
Now you can create wrapper for each Impl you got:
struct GeneratedWrapper : ImplInterface {
virtual int foo(int x, int y) {
_impl.foo(x, y);
}
virtual void bar(double x) {
_impl.bar(x);
}
private:
ImplGenerated _impl;
};
struct CustomWrapper : ImplInterface {
virtual int foo(int x, int y) {
_impl.foo(x, y);
}
virtual void bar(double x) {
_impl.bar(x);
}
private:
ImplCustom _impl;
};
Now you can use these wrapper like this:
ImplInterface* wrapper = new GeneratedWrapper(implGenerated);
This method could be much shorter using templates, let's make One wrapper for your new interface:
template<typename T>
struct EveryImplWrapper : ImplInterface {
virtual int foo(int x, int y) {
_impl.foo(x, y);
}
virtual void bar(double x) {
_impl.bar(x);
}
private:
T _impl;
};
Now you can use it like this:
ImplInterface* = new EveryImplWrapper<ImplCustom>(implCustom);
If you can't modify the existing classes, you can still add a facade to provide post-hoc polymorphism. That is:
Wrapper could not be template, because is interface class
is only partly true. You can have a non-templated interface (ABC) and a templated concrete subclass.
// publically visible parts
struct ImplInterface {
virtual ~ImplInterface() {}
virtual int foo(int x, int y) = 0;
virtual void bar(double x) = 0;
....
};
struct Wrapper {
// ...
ImplInterface *Wrapper::getImpl();
// ... do you want to keep the same impl selection across calls?
ImplInterface *m_impl;
};
// implementation details can be hidden in a cpp file
template <typename RealImpl>
struct ImplFacade: ImplInterface {
RealImpl pimpl_;
explicit ImplFacade(RealImpl *impl) : pimpl_(impl) {}
int foo(int x, int y) override { return pimpl_->foo(x,y); }
void bar(double x) override { pimpl_->bar(x); }
};
ImplInterface *Wrapper::getImpl() {
if (!m_impl) {
if (m_custom)
m_impl = new ImplFacade<ImplCustom>(m_custom);
else
m_impl = new ImplFacade<ImplGenerated>(m_generated);
}
return m_impl;
}
Ideally you should be using unique_ptr for the new member in real code.
If you can use the c++11 Standard you can use std::function to accomplish this:
struct Wrapper {
Wrapper(ImplGenerated * i):
foo(std::bind(&ImplGenerated::foo, i)),
bar(std::bind(&ImplGenerated::bar, i)) {}
Wrapper(ImplCustom * i):
foo(std::bind(&ImplCustom ::foo, i)),
bar(std::bind(&ImplCustom ::bar, i)) {}
//Now the functions are member variables but it works the same way
std::function<int(int x, int y)> foo;
std::function<void(double x)> bar;
....
//If you don't Need to destruct the impl-objects then you don't even Need to store them
};
I believe what you're wanting is to use inheritance / interface:
struct ImplInterface {
virtual int foo(int x, int y) = 0;
virtual void bar(double x) = 0;
....
};
struct ImplGenerated : public ImplInterface {
virtual int foo(int x, int y);
virtual void bar(double x);
....
};
struct ImplCustom : public ImplInterface {
virtual int foo(int x, int y);
virtual void bar(double x);
.....
};
now your getImpl() will return a ImplInterface*
Or if you can't add a base class, then in your Wrapper class instead of getImpl() do this:
int foo(int x, int y)
{
if (m_generated != nullptr)
{
return m_generated->foo(x,y);
}
else if (m_custom != nullptr)
{
return m_custom->foo(x, y);
}
throw "hey dude!";
}
I know it's a lot of work, but hey you've no base class to work with.