I am learning C++ and I have a question.
I made a class in Netbeans, which made Rectangle.h and Rectangle.cpp. I am trying to add methods that output the Area and Perimeter of the rectangle's l and w variables. I don't know how to create methods in a class and how to incorporate them in the Rectangle.h file.
Here's what I'm trying to do:
Rectangle rct;
rct.l = 7;
rct.w = 4;
cout << "Area is " << rct.Area() << endl;
cout << "Perim is " << rct.Perim() << endl;
Can someone explain how to do this? I'm so confused.
Thanks,
Lucas
In the .h file you have the class definition, where you write down the member variables en member functions (generally as prototype)
In the .cpp file you declare the methods body. Example:
rectangle.h:
class rectangle
{
public:
// Variables (btw public member variables are not a good
// practice, you should set them as private and access them
// via accessor methods, that is what encapsulation is)
double l;
double w;
// constructor
rectangle();
// Methods
double area();
double perim();
};
rectangle.cpp:
#include "rectangle.h" // You include the class description
// Contructor
rectangle::rectangle()
{
this->l = 0;
this->w = 0;
}
// Methods
double rectangle::area()
{
return this->w * this->l;
}
double rectangle::perim()
{
return 2*this->w + 2*this->l;
}
But like gmannickg said you should read a book about c++ or a real tutorial, that will explain you how the syntax works. And Object Oriented Programming (if you are not familiar with it)
Quite easy - this is just an example and one possible implementation. Note that the following adds some additional stuff (like const and a constructor) you don't necessarily need; depending on your useage.
class Rectangle {
private:
double l, w;
// This constructor has optional arguments, meaning you can skip them (which will result in them being set to 0).
public:
Rectangle(const double l = 0, const double w = 0);
double Area(void) const; // the const keyword after the parameter list tells the compiler that this method won't modify the actual object
double Perim(void) const;
}
Rectangle::Rectangle(const double _l, const double _w) : l(_l), w(_w) { // this is an initializer list - as an alternative, here it would be possible to just assign the values inside the function body
}
double Rectangle::Area(void) const {
return l * w;
}
double Rectangle::Perim(void) const {
return l + l + w + w;
}
The header (.h) file is mainly concerned with specifying the interface. While you can implement functions there as well, you typically do not. Instead, you define the class in the header, and then implement it in the .cpp (.hpp, whatever) file. For example, your rectangle class:
// Rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle {
public:
// constructors, just initialize our private members
Rectangle(int x, int y, int w, int h)
: _x(x), _y(y), _w(w), _h(h) { }
Rectangle() : _x(0), _y(0), _w(0), _h(0) { }
// implement these in Rectangle.cpp
int get_x();
void set_x(int x);
int get_y();
void set_y(int y);
int get_width();
void set_width(int w);
int get_height();
void set_height(int h);
int Area();
int Perim();
private:
int _x, _y, _w, _h;
};
#endif
// Rectangle.cpp
#include "Rectangle.h"
#include <algorithm>
using std::max;
int Rectangle::get_x() {
return _x;
}
void Rectangle::set_x(int x) {
_x = x;
}
int Rectangle::get_y() {
return _y;
}
void Rectangle::set_y(int y) {
_y = y;
}
int Rectangle::get_width() {
return _w;
}
void Rectangle::set_width(int w) {
_w = max(w, 0);
}
int Rectangle::get_height() {
return _h;
}
void Rectangle::set_height(int h) {
_h = max(h, 0);
}
int Rectangle::Area() {
return _w * _h;
}
int Rectangle::Perim() {
return _w * 2 + _h * 2;
}
Related
I am trying to make a constructor for my Input class I get this error:
Severity Code Description Project File Line Suppression State
Error (active) E0291 no default constructor exists for class "Vector2" RunGameEngine C:\Users\imman\source\repos\RunGameEngine\RunGameEngine\Run\Input.cpp 5
for some reason intelisense wants me to create a default constructor for Vector2 even though I have one for it.
Input.h:
#pragma once
#include <GLFW/glfw3.h>
#include "Vector.h"
#include "Window.h"
class Input
{
public:
Input(GLFWwindow* window);
bool isKeyPressed(float key);
Vector2 getMousePos();
private:
bool m_keys[348];
Vector2 m_mousePos;
GLFWwindow* m_window;
};
Input.cpp:
#include "Input.h"
Input::Input(GLFWwindow* window)
{
m_window = window;
}
Vector2 Input::getMousePos()
{
glfwGetCursorPos(m_window, &m_mousePos.x, &m_mousePos.y);
return m_mousePos;
}
bool Input::isKeyPressed(float key)
{
return false;
}
Vector.h:
#pragma once
struct Vector2
{
double x, y;
Vector2(double x, double y)
{
this->x = x;
this->y = y;
}
};
struct Vector3
{
double x, y, z;
Vector3(double x, double y, double z)
{
this->x = x;
this->y = y;
this->z = z;
}
};
I would do
Vector2 Input::getMousePos()
{
double Pos_x;
double Pos_y;
glfwGetCursorPos(m_window, &Pos_x, &Pos_y);
return Vector2(Pos_x, Pos_y);
}
and just skip the m_mousePos member. You don't really want to save that anyway, do you?
I am getting a compilation error saying " ‘PointType’ is not a member of ‘Point’ " I do not know what I need to implement in my code. Been thinking for a while now. I've tried adjusting the codes here and there a few times. But could not think of a solution for this. I'm a little confused by what "Point point(Point::PointType(x, y), depth);" in the main() wants. What exactly is PointType(x,y)? Can anyone enlighten me with what I should do? Would appreciate anyone's help on this. Side Note: Main() can't be touched. Thanks!
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
struct PointType
{
float x;
float y;
PointType(const float x1, const float y1) :x(x1),y(y1){}
};
class Object
{
private:
float d;
PointType * pt;
public:
Object(float n) : d(n){}
float depth() const
{
return d;
}
};
class Point :public Object
{
private:
PointType mpoint;
public:
Point(const PointType& pt, float& y1) : mpoint(pt), Object(y1) {}
virtual ~Point();
};
Main file:
const float EPSILON = 1e-5f;
bool is_near(float x, float y)
{
return std::abs(x - y) < EPSILON;
}
float frand()
{
return 10.0f * float(rand()) / float(RAND_MAX);
}
int main()
{
srand(unsigned(time(0)));
int count = 0;
int max_count = 0;
float x = frand();
float y = frand();
float depth = frand();
Point point(Point::PointType(x, y), depth);
if (is_near(point.depth(), depth))
{
++count;
}
else
{
std::cout << " - Point::depth test failed" << std::endl;
}
++max_count;
}
You've got a set circular declarations that can't be resolved if you can't change main(). You currently have PointType as a struct outside of the Point class. That's fine, but then you need to change the line in main() from:
Point point(Point::PointType(x, y), depth);
to:
Point point(PointType(x, y), depth);
But if you can't do that, then you can't ever compile this because Point is a subclass of Object, but Object requires a Point::PointType which can't have been defined yet. In order to have PointType be owned by Point, you need to declare it like this:
class Point :public Object
{
struct PointType
{
float x;
float y;
PointType(const float x1, const float y1) :x(x1),y(y1){}
};
private:
PointType mpoint;
public:
Point(const PointType& pt, float& y1) : mpoint(pt), Object(y1) {}
virtual ~Point();
};
But once you put PointType into Point, you can't declare any member of Object to have a type of Point::PointType because Point inherits from Object.
You could declare Object::pt to be a void* but that throws away type information which is dangerous.
I need to be able to use a base pointer to hold the address of either a
rectangle or a circle. Which one would be determined at run time. I then want to
use the pointers to call different virtual functions depending on which type
they are. I can get this concept to work if the functions only use one Shape
pointer. However many of my functions require two objects to work.
If I use a pure virtual functions, both Rectangle and Circle classes become
abstract and I can not use the objects (error C2259). If I declare the functions
as I did down below, all of the calls go to the Base class Shape. Any help is
greatly appreciated.
class Shape {
public:
virtual double overlappingArea(const Shape&)const {return 0;};
//replacing with a pure virtual function causes the other classes to become abstract
//virtual double overlappingArea(const Shape&)const = 0;
//This returns error C2259 (or pure virtual function has no overload)
//I know this is because the program has no overloads with identical parameters
};
class Rectangle : virtual public Shape {
public:
Rectangle(int X, int Y, int L, int W) : x(X), y(Y), l(L), w(W) {}
double overlappingArea(const Rectangle& R)const {
double area = 1.1;
//code that finds the overlapping area
return area;
}
double overlappingArea(const Circle& C)const {
double area = 1.2;
//code that finds the overlapping area
return area;
}
private:
int x, y, l, w;
};
class Circle: virtual public Shape {
public:
Circle(int X, int Y, int R) : x(X), y(Y), r(R) {}
double overlappingArea(const Rectangle& R)const {
double area = 2.1;
//code that finds the overlapping area
return area;
}
double overlappingArea(const Circle& C)const {
double area = 2.2;
//code that finds the overlapping area
return area;
}
private:
int x, y, r;
};
int main() {
Shape* F1 = new Rectangle(0,0,1,1);
Shape* F2 = new Rectangle(1,1,2,2);
Shape* C1 = new Circle(0,0,1);
Shape* C2 = new Circle(1,1,2);
double areaFF, areaFC, areaCC;
areaFF = F1->overlappingArea(*F2);
areaFC = F1->overlappingArea(*C1);
areaCC = C1->overlappingArea(*C2);
return 0;
}
All the areas end up equaling 0.
I want areaFF = 1.1 , areaFC = 1.2 , areaCC = 2.2
Thanks for the help
Working code if you're interested
#include <iostream>
using namespace std;
class Rectangle;
class Circle;
class Shape {
public:
virtual double overlapwith(const Shape&)const = 0;
virtual double overlap(const Rectangle&)const = 0;
virtual double overlap(const Circle&)const = 0;
};
class Circle : public Shape {
public:
Circle() : x(0), y(0), r(0) {
}
Circle(int X, int Y, int R) : x(X), y(Y), r(R) {
}
double overlapwith(const Shape &with)const {
cout << "\nCirc::overlapwith(const Shap&)const";
return with.overlap(*this);
}
double overlap(const Rectangle &w)const {
cout << "\nCirc::overlap(const Rect&)const";
return 12;
}
double overlap(const Circle &w)const {
cout << "\nCirc::overlap(const Circ&)const";
return 11;
}
private:
int x, y, r;
};
class Rectangle : public Shape {
public:
Rectangle() : x(0), y(0), l(0), w(0) {
}
Rectangle(int X, int Y, int L, int W) : x(X), y(Y), l(L), w(W) {
}
double overlapwith(const Shape &with)const {
cout << "\nRect::overlapwith(const Shap&)const";
return with.overlap(*this);
}
double overlap(const Rectangle &w)const {
cout << "\nRect::overlap(const Rect&)const";
return 22;
}
double overlap(const Circle &w)const {
cout << "\nRect::overlap(const Circ&)const";
return 21;
}
private:
int x, y, l, w;
};
int main() {
Shape* F1 = new Rectangle(0,0,1,1);
Shape* F2 = new Rectangle(1,1,2,2);
Shape* C1 = new Circle(0,0,1);
Shape* C2 = new Circle(1,1,2);
double ff, fc, cf, cc;
ff = F1->overlapwith(*F2);
fc = F1->overlapwith(*C2);
cf = C1->overlapwith(*F2);
cc = C1->overlapwith(*C2);
cout << "\n\n\tff : " << ff
<< "\n\tfc : " << fc
<< "\n\tcf : " << cf
<< "\n\tcc : " << cc;
int pb; cin >> pb;
return 0;
}
Define two more pure virtual methods in the base class, in addition to the existing virtual methods, which can be pure. You will need to do some simple forward declarations:
class Rectangle;
class Circle;
class Shape {
public:
virtual double overlappingArea(const Shape&) const=0;
virtual double overlappingAreaWith(const Rectangle&) const=0;
virtual double overlappingAreaWith(const Circle&) const=0;
};
In each subclass, implement the first virtual method (the existing one) by invoking overlappingAreaWith() for the passed Shape & parameter, passing *this as the parameter:
class Rectangle {
// ...
double overlappingArea(const Shape &with) const override
{
return with.overlappingAreaWith(*this);
}
};
class Circle {
// ...
double overlappingArea(const Shape &with) const override
{
return with.overlappingAreaWith(*this);
}
};
Now, implement the other two overlappingAreaWith() methods in both Circle and Rectangle subclasses. They will now receive the other object, as either a Circle or a Rectangle parameter, as the case may be.
Each subclass is correctly implementing all three pure virtual methods.
I'm new to progamming in C++. I have a good background with Java but C++ is different on many things and I have a question about one of the regarding .h and .cpp files.
I have the following files for a point object with x and y position:
Point.h
#ifndef POINT_H_
#define POINT_H_
class Point{
Point();
Point(int newX, int newY);
public:
int getX();
int getY();
void setX(int newX);
void setY(int newY);
void moveBy(int moveX, int moveY);
Point reverse();
private:
int x;
int y;
};
#endif
Point.cpp
#include "Point.h"
using namespace Point;
Point::Point(int newX, int newY){
x = newX;
y = newY;
}
int Point::getX(){
return x;
}
int Point::getY(){
return y;
}
void Point::setX(int newX){
x = newX;
}
void Point::setY(int newY){
y = newY;
}
void Point::moveBy(int moveX, int moveY){
x += moveX;
y += moveY;
}
Point Point::reverse(){
return Point(y,x);
}
I was wondering if there was a way of avoinding the Point::Point part like with std::cout by using namespace.
Thank you
You aren't required to separate your declaration and definition, and these functions are incredibly trivial. So including them in the class definition may actually allow the compiler to perform numerous additional optimizations.
So you could discard the .cpp entirely and the header becomes:
#ifndef POINT_H_
#define POINT_H_
class Point
{
int x_ { 0 };
int y_ { 0 };
public:
Point() = default;
Point(int x, int y) : x_(x), y_(y) {}
int getX() const { return x_; }
int getY() const { return y_; }
void setX(int x) { x_ = x; }
void setY(int y) { y_ = y; }
void moveBy(int x, int y) { x_ += x, y_ += y; }
Point reverse() const { return Point(y_, x_); }
};
#endif
But you can't avoid the "Point::" part when defining the members outside of the class declaration.
If you want to avoid typing the "Point::" in front of the getX, getY etc., then the answer is "no", unfortunately. In C++ and the name of any class (like "Point") is not a namespace, it's a scope.
What you can only do is inlining the method, defining into the class declaration.
class Point {
public:
void a_method() {
// all the code here!
}
};
You can't avoid "the Point::Point part," unless you declare the construction inline in the class declaration. The first "Point" defines the scope of the function, and the second "Point" is the name of the constructor function.
However, you could define the constructor(s) inline, like so:
class Point
{
Point()
{
x = 0;
y = 0;
}
Point(int newX, int newY);
{
x = newX;
y = newY;
}
// ...
};
Or:
class Point
{
Point() : x(0), y(0) {}
Point(int newX, int newY) : x(newX), y(newY) {}
// ...
};
Or:
class Point
{
Point(int newX = 0, int newY = 0) : x(newX), y(newY) {}
// ...
};
I am currently rewriting C code into C++ code. While doing that I am replacing structs with classes. That means that some of the variables go from public to private. Now during the transition phase I want to do some error checking by compiling the program sometimes and running it. Thus I intended to have public and private variables at the same time, which are linked, i.e. when I write something into the private variable, the public variable also changes. Nevertheless I only want to write to the private variables by using separate functions, i.e. having the public variables as read-only variables. My current approach is:
#include <iostream>
#include <stdio.h>
class test_vec
{
private:
int x, y;
int data[2];
public:
int x_ext, y_ext;
int data_ext[2];
test_vec(int x, int y)
{
this->x = x;
this->y = y;
this->x_ext = this->x;
this->y_ext = this->y;
}
~test_vec()
{}
void set_x(int x)
{
this->x = x;
}
void set_y(int y)
{
this->y = y;
}
};
int main(void)
{
std::cout << "Hello World\n";
test_vec test(1, 2);
printf("test has the properties (%d, %d)\n", test.x_ext, test.y_ext);//So far, so good
test.set_x(4);
test.set_y(10);
printf("test has the properties (%d, %d)\n", test.x_ext, test.y_ext);//Not updated!
return 0;
}
How can I change the links between the variables? At the moment I already have two pointers copied into each other, but how can I "lock" the external variable onto the internal variable?
Not sure if it's a good design pattern since inline getters are fast but you could create constant references to your private variables:
class test_vec
{
private:
int x, y;
int data[2];
public:
const int &x_ext, &y_ext;
int data_ext[2];
// you have to initialize the references before constructor body
// references cannot be let uninitialized
test_vec(int x, int y) : x_ext(this->x), y_ext(this->y)
{
this->x = x;
this->y = y;
}
~test_vec()
{}
inline void set_x(int x)
{
this->x = x;
}
inline void set_y(int y)
{
this->y = y;
}
};
when x or y changes x_ext and y_ext follow:
Hello World
test has the properties (1, 2)
test has the properties (4, 10)
Bonus: constant references cannot be modified. That's the closest thing of a read property that you got here :)
If you don't want that restriction, just remove the const qualifier, but since you're encouraging encapsuation now that you have C++ I would let it as is and let the writers hit the wall on that (not to mention a good sed/regex replacement could refactor all your writes automatically)
You can use references for these purposes.
Say you have this setup:
class myclass{
public:
myclass(int pa, float pb);
int get_a() const {return a;}
float get_b() const {return b;}
void set_a(int v) {a=v;}
void set_b(float v) {b=v;}
private:
//These are the real values, private
int a;
float b;
public:
//These are the references, public
int& ref_to_a;
float& ref_to_b;
}
myclass::myclass(int pa, float pb)
:a(pa), b(pb), ref_to_a(a), ref_to_b(b)
{
}
You can go like this:
myclass c(33, 12.3f);
c.set_a(12);
c.set_b(111.1f);
//This...
std::cout<<c.ref_to_a<<" "<<c.ref_to_b<<std::endl;
//Should be the same as this...
std::cout<<c.get_a()<<" "<<c.get_b()<<std::endl;
Notice the access settings: the references are public, meaning you can write and read from them. If you want them to be read only you can play with the constness.
I wouldn't bother. Just make the members public for the moment, and when you have fixed all the external references, make them private.
class test_vec
{
public: // For now. Will become private later
int x, y;
public: // For now.
int data[2];
public: // For ever
test_vec(int x, int y)
: x(x), y(y) // Prefer initialization to assignment.
{
}
~test_vec()
{}
void set_x(int x)
{
this->x = x;
}
void set_y(int y)
{
this->y = y;
}
int get_x() const { return x; } // etc
};
If you really wanted to, you could make x_ext be a reference to const - but it's much more idiomatic in C++ to make getters be functions.
class test_vec
{
private:
int x, y;
int data[2];
public:
int const& x_ext;
int const& y_ext;
test_vec(int x_, int y_)
: x(x_), y(y_)
, x_ext(x), y_ext(y) // You *have* to use initialization here.
{
}
~test_vec()
{}
void set_x(int x)
{
this->x = x;
}
void set_y(int y)
{
this->y = y;
}
};