C++ inheritance (overriding constructors) - c++

I am learning OpenGL w/ C++. I am building the asteroids game as an exercise. I'm not quite sure how to override the constructors:
projectile.h
class projectile
{
protected:
float x;
float y;
public:
projectile();
projectile(float, float);
float get_x() const;
float get_y() const;
void move();
};
projectile.cpp
projectile::projectile()
{
x = 0.0f;
y = 0.0f;
}
projectile::projectile(float X, float Y)
{
x = X;
y = Y;
}
float projectile::get_x() const
{
return x;
}
float projectile::get_y() const
{
return y;
}
void projectile::move()
{
x += 0.5f;
y += 0.5f;
}
asteroid.h
#include "projectile.h"
class asteroid : public projectile
{
float radius;
public:
asteroid();
asteroid(float X, float Y);
float get_radius();
};
main.cpp
#include <iostream>
#include "asteroid.h"
using namespace std;
int main()
{
asteroid a(1.0f, 2.0f);
cout << a.get_x() << endl;
cout << a.get_y() << endl;
}
error I'm getting:
main.cpp:(.text+0x20): undefined reference to `asteroid::asteroid(float, float)'

You can use the : syntax to call the parent's constructor:
asteroid(float X, float Y) : projectile (x ,y);

Ok, just figured it out.
I actually don't have asteroid constructors defined because I thought they would inherit. But I think I have to do the following in asteroid.h:
asteroid(float X, float Y) : projectile(X, Y){];

You need a asteroid.cpp.
Even though inheriting from projectile, for non-default constructors (i.e., asteroid(float,float)), you still need to define the child class constructor.
You'll also need to define get_radius, as it's not defined in your base class.
Here's how that might look (I've taken the liberty of passing values for radius into both ctors):
#include "asteroid.h"
asteroid::asteroid(float r)
: projectile()
{
radius = r;
}
asteroid::asteroid(float x, float y, float r)
: projectile(x, y)
{
radius = r;
}
float asteroid::get_radius()
{
return radius;
}

Related

Function only returning 1's for the area and disregards the formula?

I am trying to calculate area of all shapes (rectangle, rhombus, triangle, circle) through using virtual and override methods. But when I execute the code it returns 1 for the area for all shapes even though I have tried with the rectangle to alter it to input the given area multiple times in int main() it still only outputs "My figure type is My area is 1 My figure type is Triangle My area is 1 My figure type is Circle My area is 1 My figure type is Rhombus My area is 1"
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
class Figure
{
protected:
double x;
double y;
string type;
public:
Figure(double m_x, double m_y) : x{ m_x }, y{ m_y } {};
virtual double area(double x, double y) { return 0; };
Figure(double m_x, double m_y, double x = 0, double y = 0) { m_x = x; m_y = y; }
virtual void Print() const final;
Figure(const Figure& obj);
Figure() {};
};
class Rectangle : public Figure
{
public:
Rectangle(double x, double y)
{
this->x = x;
this->y = y;
type = " Rectangle";
double area();
}
double area(double x, double y) override {
return x * y;
}
Rectangle() {};
};
class Triangle : public Figure
{
public:
Triangle(double x, double y)
{
this->x = x;
this->y = y;
type = " Triangle";
double area();
}
double area(double x, double y)override {
return x * y / 2;
}
Triangle() {};
};
class Circle : public Figure
{
public:
Circle(double x, double y)
{
this->x = x;
this->y = y;
type = " Circle";
double area();
}
double area(double x, double y)override {
return pow(x, 2) * 3.14;
}
Circle() {};
};
class Rhombus : public Figure
{
public:
Rhombus(double x, double y)
{
this->x = x; this->y = y; type = " Rhombus"; double area();
}
double area(double x, double y)override {
return x * y / 2;
}
Rhombus() {};
};
void Figure::Print() const
{
cout << " My figure type is" << type
<< " My area is " << &Figure::area;
}
int main()
{
Rectangle rectangle;
rectangle.area(5.4,6.2);
rectangle.Print();
Triangle triangle(4.5,5.3);
triangle.Print();
Circle circle(6.6, 8.8);
circle.Print();
Rhombus rhombus(3.4,5.4);
rhombus.Print();
}
You are getting 1 because a valid function pointer is treated as true.
You should call the function area like Figure::area(x, y) instead of getting the address of the function area like &Figure::area.
it's simple. really.
When you do
rectangle.area(x, y);
you just return the value you obtain from the variables that you passed in. You never assign a value to the x and y of the actual rectangle. So when you do print the area of the rectangle you use its real x and y, which do not have a value assigned to them, hence resulting in a 1. it's the same for the other shapes.

C++ issue with standard library

I'am making this post because i have for the first time of my life an incomprehensible error from visual studio community 2017 :
I simply can't use others members of std then "nullptr_t" in all my classes except in the main.cpp ....
The auto-completion of visual only suggest me "nullptr_t" when I write "std::" except in the main.cpp. It's incomprehensible.
main.cpp code:
#include <SFML/Graphics.hpp>
int main()
{
return 0;
}
Point class code :
#pragma once
class Point
{
private:
float _x;
float _y;
public:
Point();
Point(float x, float y);
Point(const Point& p);
~Point();
float getx() { return _x; }
float gety() { return _y; }
void setx(float x) { _x = x; }
void sety(float y) { _y = y; }
};
/************************************************************************/
#include "pch.h"
#include "Point.h"
Point::Point()
{
_x = 0.0;
_y = 0.0;
}
Point::Point(float x, float y)
{
_x = x;
_y = y;
}
Point::Point(const Point& p)
{
_x = p._x;
_y = p._y;
}
Point::~Point()
{
}
Hexagon class :
#pragma once
class Hexagon
{
private:
Point _center;
float _diameter;
public:
Hexagon();
Hexagon(Point center, float diameter);
~Hexagon();
};
/***********************************************************************/
#include "pch.h"
#include "Hexagon.h"
#include "Point.h"
Hexagon::Hexagon() : _center()
{
_diameter = 10;
}
Hexagon::Hexagon(Point center, float diameter) : _center(center)
{
_diameter = diameter;
}
Hexagon::~Hexagon()
{
}
You just need to include the iostream library or add this line of code where you need it to the includes.
#include<iostream>

Defining header files in C++

To start off with, I'll mention I come mainly from a Java background. I do have exposure with C and understand most concepts behind C++. I'm trying to help myself learn more about the language and can't seem to figure out headers. I understand why to use them in addition to cpp files and all of that. My problem is trying to actually manage working with them. For example, defining a Vector3 header with private float variables and then overload operating. My problem comes in when I attempt to define the constructor and methods in the cpp file. I can't seem to figure out how to get access to the private variables without specifically defining the functions and the constructor in the header, which more or less leads me to believe I don't need both a header and cpp file in this instance.
Here's how I've defined the header file currently (which works, but isn't undefined as it should be):
#pragma once
#ifndef __Vector_3_H__
#define __Vector_3_H__
namespace VectorMath {
class Vector3 {
public:
Vector3(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
}
Vector3 operator+(Vector3 vector) {
return Vector3(x + vector.x, y + vector.y, z + vector.z);
}
Vector3 operator-(Vector3 vector) {
return Vector3(x - vector.x, y - vector.y, z - vector.z);
}
Vector3 operator*(Vector3 vector) {
return Vector3(x * vector.x, y * vector.y, z * vector.z);
}
Vector3 operator/(Vector3 vector) {
return Vector3(x / vector.x, y / vector.y, z / vector.z);
}
float getX() {
return x;
}
float getY() {
return y;
}
float getZ() {
return z;
}
private:
float x;
float y;
float z;
};
}
#endif
It needs to look more like this instead:
Vector_3.h:
#ifndef Vector_3_H
#define Vector_3_H
#pragma once
namespace VectorMath {
class Vector3 {
public:
Vector3(float x, float y, float z);
Vector3 operator+(Vector3 vector);
Vector3 operator-(Vector3 vector);
Vector3 operator*(Vector3 vector);
Vector3 operator/(Vector3 vector);
float getX();
float getY();
float getZ();
private:
float x;
float y;
float z;
};
}
#endif
Vector_3.cpp:
#include "Vector_3.h"
namespace VectorMath {
Vector3::Vector3(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
}
Vector3 Vector3::operator+(Vector3 vector) {
return Vector3(x + vector.x, y + vector.y, z + vector.z);
}
Vector3 Vector3::operator-(Vector3 vector) {
return Vector3(x - vector.x, y - vector.y, z - vector.z);
}
Vector3 Vector3::operator*(Vector3 vector) {
return Vector3(x * vector.x, y * vector.y, z * vector.z);
}
Vector3 Vector3::operator/(Vector3 vector) {
return Vector3(x / vector.x, y / vector.y, z / vector.z);
}
float Vector3::getX() {
return x;
}
float Vector3::getY() {
return y;
}
float Vector3::getZ() {
return z;
}
}
If you want to use a cpp file for your constructor you should write
// File Vector3.cpp
#include "Vector3.h"
namespace VectorMath {
Vector3::Vector3 (float x, float y, float z)
{
this->x=x;
//...
}
The addition should be implemented as follows if you keep it in the same namespace
Vector3 Vector3::operator+(const Vector3& v)
{
return Vector3 (x+v.x,y+v.y,z+v.z);
}
}
If you want to move the implementations of member functions away from the header file, you still need to declare them in the definition of the class. For example:
// Vector1.h
#pragma once
#ifndef VectorMath_Vector1_H
#define VectorMath_Vector1_H
namespace VectorMath {
class Vector1 {
public: // Methods:
// This is a definition for a default constructor:
Vector1() noexcept : m_x(0) {}
// This is a declaration for another constructor:
Vector1(float x) noexcept;
// This is a declaration of a member function:
Vector1 operator+(Vector1 const & rhs) const noexcept;
private: // Fields:
float m_x;
}; // class Vector1
} // namespace VectorMath {
#endif // VectorMath_Vector1_H
// Vector1.cpp
#include "Vector1.h"
namespace VectorMath {
// Definition of the other constructor:
Vector1::Vector1(float x) noexcept
: m_x(x)
{}
// Definition of the binary + operator:
Vector1 Vector1::operator+(Vector1 const & rhs) const noexcept
{ return m_x + rhs.m_x; }
} // namespace VectorMath {

C++ Error: "Multiple markers at this time: no matching function for call to" in constructor

Multiple markers at this line
- candidates are:
- no matching function for call to
'Coordinate::Coordinate()'
I am getting this error in the constructor of my class and I don't understand why. Here is the code involved:
RadialScan header
#ifndef RADIALSCAN_H_
#define RADIALSCAN_H_
#include "EasyBMP/EasyBMP.h"
#include <vector>
#include "Coordinate.h"
using namespace std;
class RadialScan {
vector<int> distanceTimeSeries;
vector<Coordinate> timeSeries;
BMP image;
Coordinate center;
Coordinate getNextPoint(Coordinate c);
bool isBlack(Coordinate c);
void computeTimeSeries();
public:
RadialScan(char* filename);
vector<int> getDistances();
vector<Coordinate> getCoordinates();
};
#endif
RadialScan class (all the methods are implemented, but the error is in the constructor and that's the code I'm providing):
#include "RadialScan.h"
RadialScan::RadialScan(char* filename){
image.ReadFromFile(filename);
int centerX = image.TellWidth()/2;
int centerY = image.TellHeight()/2;
center = Coordinate(centerX, centerY);
}
...
The error seems to be in the constructor. If I remove the constructor everything seems to compile correctly. If I delete the code inside the constructor I'm still getting the error. I don't understand why it keeps asking me for the Coordinate::Coordinate() constructor even when I don't have a coordinate object defined in the RadialScan(char* filename) constructor.
Additionally, these are the files for the Coordinate class:
header:
#ifndef COORDINATE_H_
#define COORDINATE_H_
class Coordinate {
int x;
int y;
public:
Coordinate(int x, int y);
void setX(int oneX);
void setY(int oneY);
int getX();
int getY();
double getMagnitude();
Coordinate operator-(const Coordinate&);
bool operator==(const Coordinate&);
Coordinate operator=(const Coordinate&);
};
#endif
cpp class:
#include "Coordinate.h"
#include <math.h>
Coordinate::Coordinate(int oneX, int oneY) {
x = oneX;
y = oneY;
}
//Setters
void Coordinate::setX(int oneX) {
x = oneX;
}
void Coordinate::setY(int oneY) {
y = oneY;
}
//Getters
int Coordinate::getX() {
return x;
}
int Coordinate::getY() {
return y;
}
double Coordinate::getMagnitude() {
return sqrt(x * x + y * y);
}
Coordinate Coordinate::operator-(const Coordinate& p) {
return Coordinate(x - p.x, y - p.y);
}
bool Coordinate::operator==(const Coordinate& p) {
return x == p.x && y == p.y;
}
Coordinate Coordinate::operator=(const Coordinate& p) {
return Coordinate(p.x, p.y);
}
Your constructor must look like
RadialScan::RadialScan(char* filename) : center (0, 0) {
image.ReadFromFile(filename);
int centerX = image.TellWidth()/2;
int centerY = image.TellHeight()/2;
center = Coordinate(centerX, centerY);
}
this because you did not implement default constructor and you can not create center object by default, so the only way is to call explicity Coordinate constructor with some default values.

How to make a good set/get method

For example, we have this class:
class Coord
{
double x;
double y;
double z;
public:
Coord() { x = y = z = 0; }
void set(double xx, double yy, double zz)
{
x = xx;
y = yy;
z = zz;
}
void set_x(double xx) { x = xx; }
void set_y(double yy) { y = yy; }
void set_z(double zz) { z = zz; }
double get_x() { return x; }
double get_y() { return y; }
double get_z() { return z; }
};
On these 7 methods we can set and get x,y and z of a coordinate. I am interested in create less methods set() and get() where I can call something like that:
int main()
{
Coord c;
c.set_x(5); /* only set x */
c.set_y(6); /* or y */
c.set_z(7); /* or z */
c.set(1,2,5); /* or setting x, y and z */
c.get_x(); /* only get x */
c.get_y(); /* or y */
c.get_z(); /* or z */
}
If the Coord class is that simple, it could also be a struct.
Anyway you can write something like:
class Coord
{
public:
enum xyz {x = 0, y, z};
Coord() : vec{x, y, z} {}
template<xyz C> void set(double v) { vec[C] = v; }
template<xyz C> double get() const { return vec[C]; }
void set(double xx, double yy, double zz)
{
set<Coord::x>(xx);
set<Coord::y>(yy);
set<Coord::z>(zz);
}
private:
double vec[z + 1];
};
and use the class this way:
Coord c;
c.set<Coord::x>(5); /* only set x */
c.set<Coord::y>(6); /* or y */
c.set<Coord::z>(7); /* or z */
c.set(1,2,5); /* or setting x, y and z */
c.get<Coord::x>(); /* only get x */
c.get<Coord::y>(); /* or y */
c.get<Coord::z>(); /* or z */
getters and setters are meant to protect your data and provide encapsulation.
For example they allow you to add side effects to getting and setting operations (such as writing to a log), or allow you to catch invalid values early before they cause horrible problems later (For example preventing values greater than n being set).
Here's a brief and contrived setter example:
void set_x(int x)
{
// prevent an invalid value for x
if( x > 11 ) x = 11;
// set x
this.x = x;
// log the operation
log("user set x to {0}", x);
}
Assuming your c.set.x(5) example is not using some whacky preprocessor macros, it would require that the Coord class have a member variable called set with methods
x()
y()
z()
This would require just as much code as writing a set_x(), set_y() and set_z() method in your Coord class, but the methods would not belong to the class Coord, instead belonging to another class that is itself used as a member variable of Coord. Doing so would not really make any logical sense... the x, y, and z values belong to Coord and operations on them are operations on the Coord.
Furthermore the methods x() y() and z() would no longer obey the general principle of making methods verbs. Anyone reading the class with those methods would have no idea what function z() is supposed to do!
It would also create a refactoring nightmare: If for example in the future a business requirement appeared that meant no Coords could ever have values of x greater than 21 somone maintaining your code would have to change a class that is a member of Coord rather than the Coord class itself.
Encapsulation with getter and setter methods is often a really good idea and in C++ with the benefit of inlining it can even add no runtime overhead. But keep to the principle "Make everything as simple as possible, but not simpler." In other words get_x() and set_x() are widely understood, useful, easily refactored, convenient, self-documenting and performant... other approaches are likely to be less so.
First: Your usage of c.set.x would not work because you would call a public element set on your object c and where set has a public element x.
I find both classes lack standards of clean code and usual style of getter and setter - even without specifying any language.
A usual way would be to create the following:
class Coord
{
double x;
double y;
double z;
public:
Coord() {
x = 0;
y = 0;
z = 0;
}
Coord(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
void setX(double x) { this.x = x; }
void setY(double y) { this.y = y; }
void setZ(double z) { this.z = z; }
double getX() { return x; }
double getY() { return y; }
double getZ() { return z; }
};
Though some prefer to use m_x as setter variable parameter or any other convention.
Anyhow everyone would directly understand your code. Is able to set and get coordinate values for x, y, z and it would look pretty standard-default-behaviour if someone does following:
Coord P(10, 15, 20);
std::cout << P.getX() << " " << P.getY() << std::endl;
P.setX(-10);
P.setZ(40);
You've already gotten some good answers, but you could also use an enum if you really want a syntax with fewer setters and getters. The client syntax can get a little clunky and awkward, but it of course depends on what you're looking for!
#include <iostream>
class Coord {
public:
enum Axis {
X = 0,
Y,
Z,
NUM_AXES
};
// Using extended initializer lists (C++11)
Coord() : axes_{0, 0, 0} {}
Coord(double x, double y, double z) : axes_{x, y, z} {}
void set(Axis a, double d) {
axes_[a] = d;
}
double get(Axis a) const {
return axes_[a];
}
private:
double axes_[NUM_AXES];
// Copy constructor and assgn. operator included for good measure
Coord(const Coord &);
void operator=(const Coord &);
};
int main()
{
Coord c(1, 2, 3);
std::cout << "X: " << c.get(Coord::X) << std::endl;
std::cout << "Y: " << c.get(Coord::Y) << std::endl;
std::cout << "Z: " << c.get(Coord::Z) << std::endl;
c.set(Coord::Y, 4);
std::cout << "Y: " << c.get(Coord::Y) << std::endl;
return 0;
}
This strange code does exactly what you ask - just C++ fun. Don't do this!
#include <iostream>
using namespace std;
class Coord {
double x;
double y;
double z;
public:
class Setter {
public:
Setter(Coord& coord) : c(coord) {}
void x(double value) { c.x = value; }
void y(double value) { c.y = value; }
void z(double value) { c.z = value; }
void operator()(double x, double y, double z) { c.x = x; c.y = y; c.z = z; }
private:
Coord& c;
};
class Getter {
public:
Getter(Coord& coord) : c(coord) {}
double x() { return c.x; }
double y() { return c.y; }
double z() { return c.z; }
private:
Coord& c;
};
Setter set;
Getter get;
Coord() : set(*this), get(*this) { x = y = z = 0; }
friend class Setter;
};
int main()
{
Coord c;
cout << c.get.x() << " " << c.get.y() << " " << c.get.z() << endl;
c.set.x(1);
c.set.y(2);
c.set.z(3);
cout << c.get.x() << " " << c.get.y() << " " << c.get.z() << endl;
c.set(5, 6, 7);
cout << c.get.x() << " " << c.get.y() << " " << c.get.z() << endl;
return 0;
}
Output:
0 0 0
1 2 3
5 6 7
The more or less standard way to expose this, if validation is not a concern, is to return mutable references from the non-const accessor, and values from the const one. This allows you to separate the interface from storage, while not making the syntax too heavy.
private:
double m_x, m_y, m_z;
public:
double & x() { return m_x; }
double & y() { return m_y; }
double & z() { return m_z; }
double x() const { return m_x; }
double y() const { return m_y; }
double z() const { return m_z; }
This will allow c.x() to obtain the value of the x coordinate whether the Coord object is const or not, and allows setting the value using the syntax c.x() = value.
In the interest of completeness, you can get exactly the syntax you want using the following code, but I would strongly recommend against it. It is a lot of extra code, provides no real benefit, and creates a syntax that is uncommon and most programmers will not find it intuitive.
The technique creates two nested classes getters and setters and exposes instances of them as public members of Coord.
This is provided as an example of how to achieve the result you asked for, but I do not recommend this approach.
class Coord
{
private:
double x, y, z;
public:
Coord();
Coord(double, double, double);
class setters {
friend class Coord;
private:
explicit setters(Coord &);
public:
setters(setters const &) = delete;
setters & operator=(setters const &) = delete;
void x(double) const;
void y(double) const;
void z(double) const;
private:
Coord & coord;
};
friend class setters;
class getters {
friend class Coord;
private:
explicit getters(Coord const &);
public:
getters(getters const &) = delete;
getters & operator=(getters const &) = delete;
double x() const;
double y() const;
double z() const;
private:
Coord const & coord;
};
friend class getters;
setters const set;
getters const get;
};
Coord::Coord() : x(0), y(0), z(0), set(*this), get(*this) { }
Coord::Coord(double px, double py, double pz) : x(px), y(py), z(pz), set(*this), get(*this) { }
Coord::setters::setters(Coord & c) : coord(c) { }
void Coord::setters::x(double px) const {
coord.x = px;
}
void Coord::setters::y(double py) const {
coord.y = py;
}
void Coord::setters::z(double pz) const {
coord.z = pz;
}
Coord::getters::getters(Coord const & c) : coord(c) { }
double Coord::getters::x() const {
return coord.x;
}
double Coord::getters::y() const {
return coord.y;
}
double Coord::getters::z() const {
return coord.z;
}
(Demo)
Actually the function can be reduce based on your requirement as follows,
class Coord
{
double x;
double y;
double z;
public:
Coord() {
x = 0;
y = 0;
z = 0;
}
void GetValues(double* x=NULL, double* y=NULL, double* z=NULL);
void SetValues(double x=0, double y=0, double z=0)
/* You can use constructors like below to set value at the creation of object*/
Coord(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
/*You can set the values of x, y & z in a single function as follows. It can be used at any time without restriction */
void SetValues(double x, double y, double z)
{
if(x > 0) //It is optional to use condition so that you can update any one variable aloen by sending other two as ZERO
{
this.x = x;
}
if(y > 0)
{
this.y = y;
}
if(z > 0)
{
this.z = z;
}
}
/*You can Get the values of x, y & z in a single function as follows. Pass By Reference id the concept you need */
void GetValues(double* x, double* y, double* z)
{
if(x != NULL) //It x is not null.
{
x = this.x;
}
if(y != NULL)
{
y = this.y;
}
if(z != NULL)
{
z= this.z;
}
}
};
while calling you can call like the following,
SetValues(10, 20, 0); //To set x and y values alone.
double x1 = 0;double y1 = 0;double z1 = 0;
GetValues(&x1, &y1, &z1)//It will return the values x1 y1 and z1 as 10, 20 & 0
You cannot do exactly what you want.
In
c.set.x(5); /* only set x */
the c.set subexpression is retrieving a field set from c (unless set is a #define-d macro, but that would be silly).