Compilation error in C++ while performing operator overloading - c++

I am learning c++ and getting the compilation error while doing operator overloading. I am attaching my code. Please have a look. The error is at line no 27.
I tried to make changes but as I am totally new to c++, I am unable to resolve this. We don't have anything like this in C.
Also, suggest me some good way to improve my coding standard and skills.
#include <iostream>
#include<string>
#include <string.h>
#include <stdlib.h>
using namespace std;
class rectangle
{
private:
int l,b;
public:
// friend
rectangle(int,int);
rectangle(rectangle &r);
void setL(int);
void setB(int);
int getL();
int getB();
int area();
int parameter();
void isSquare();
rectangle operator + (rectangle r1)
{
rectangle temp; // compilation error here ///////Line No 27:
temp.l=r1.l+l;
temp.b=r1.b+b;
return temp;
}
// void ~rectangle();
};
void rectangle:: isSquare()
{
if(l==b)
cout<<"It is square"<<endl;
else
cout<<"It is rectangle"<<endl;
}
rectangle:: rectangle(int length =0, int breadth =0)
{
setL(length);
setB(breadth);
}
rectangle:: rectangle(rectangle &r)
{
setL(r.l);
setB(r.b);
}
void rectangle::setL(int length)
{
if(length>0)
l=length;
else
l=0;
}
void rectangle::setB(int breadth)
{
if(breadth>0)
b=breadth;
else
b=0;
}
int rectangle::getL()
{
return l;
}
int rectangle::getB()
{
return b;
}
int rectangle::area()
{
return l*b;
}
int rectangle::parameter()
{
return 2*l*b;
}
//extern void print(char *s);
int main()
{
cout<<("Welcome to test codes!!! :) :) \n");
rectangle r(10,5);
rectangle r1(2,5);
rectangle r2;
cout<<"r "<<r.area()<<' '<<r.parameter()<<endl;
cout<<"r1 "<<r1.area()<<' '<<r1.parameter()<<endl;
cout<<"r2 "<<r2.area()<<' '<<r2.parameter()<<endl;
r.isSquare();
r2=r+r1;
cout<<"r2 "<<r2.area()<<' '<<r2.parameter()<<endl;
return 0;
}
Error is main.cpp:32:19: error: no matching function for call to 'rectangle::rectangle()'
rectangle temp;

Look at your constructors
rectangle(int,int);
rectangle(rectangle &r);
One that takes two integers, and one that takes another rectangle. So this means to construct a rectangle you must provide either two integers or another rectangle.
Now look at the line with the error
rectangle temp;
What's provided here? Nothing of course, but you don't have a constructor with no arguments, so this is a compilation error.
Looking at your code the best solution is this
rectangle temp(r1.l+l, r1.b+b);
return temp;
Now two integers are being provided.
BTW your code shows a complete lack of awareness of const. You're going to quickly run into trouble unless you learn about that.

The line
rectangle temp; // compilation error here ///////
is trying to create a new instance of "rectangle" without any constructor parameters. Your class does not have a constructor that takes no parameters, that's why you get the error. It has nothing to do with your operator.
You need to use:
rectangle temp(0, 0);
Or, create a constructor that takes no parameters:
in header
rectangle();
in source file
rectangle:: rectangle() {}

Related

C++, How to call a child method in the parent class

I have two classes in my project:
Style
Line
In which, Line is the child of Style, so Line inherits from Style.
I need that when I call a method of the class Style (the parent) from Line (the child), the method of Style calls a method of the child, for your better understanding here is the code:
Line calls the Style function --> Style calls the Line function
Style.h:
#pragma once
class Style
{
public:
void set_size(int width, int height);
protected:
int width, height;
};
Style.cpp:
#include "Style.h"
void Style::set_size(int width, int height)
{
Style::width = width;
Style::height = height;
}
Line.h:
#pragma once
#include "Style.h"
#include <vector>
using namespace std;
class Line : public Style
{
public:
void draw();
vector <vector<char>> matrix;
};
Line.cpp:
#include "Line.h"
void Line::draw()
{
vector <char> row;
int i, j;
for (i = 0; i < Line::height; i++)
{
row.clear();
for (j = 0; j < Line::height; i++)
{
row.push_back('-');
}
Line::matrix.push_back(row);
}
}
Main.cpp:
#include <iostream>
#include "Line.h"
using namespace std;
int main()
{
Line line;
line.set_size(10, 10);
}
Obviously, this code for now does nothing much, it only modifies Style variables.
What I expect is that when I call set_size(), in addition to changing the value of the variables width and height, it will also change the size of the matrix
I don't know how to do what I said before.
I don't even know if it is a good method that Line is a child of Style, in any case other solutions that do not include inheritance are welcome.
Thanks in advance.
You need virtual functions, it would seem that set_size is the one that should be virtual, but this is not the only way to do it.
class Style
{
public:
virtual void set_size(int width, int height);
virtual ~Style() {}
protected:
int width, height;
};
class Line : public Style
{
public:
void draw();
virtual void set_size(int width, int height)
{
Style::set_size(width, height);
... // some code to resize matrix
}
vector <vector<char>> matrix;
};
But I question if this is good design, Style should be an attribute of Line (i.e. a member variable). Inheritance doesn't seem appropriate here, which is why you are struggling to write the code.
I tried to have implementation and declaration in the same file. but you can structure it as you may feel good for your project.
#include <iostream>
#include <vector>
using namespace std;
class Line;
class Style
{
public:
void set_size(int width, int height){
w = width;
h = height;
}
void print(){
cout << w << ", " << h << endl;
}
friend class Line;
protected:
int w, h;
};
class Line : public Style
{
public:
void draw(){
vector <char> row;
int i, j;
for (i = 0; i < w; i++)
{
row.clear();
for (j = 0; j < h; i++)
{
row.push_back('-');
}
matrix.push_back(row);
}
}
vector<vector<char>> matrix;
};
int main()
{
Line line;
line.set_size(10, 10);
line.print();
line.set_size(20, 20);
line.print();
}
We can just overload set_size within Line and call the other set_size from there and also the draw function to recreate the matrix.
This solution provides simple static polymorphism, that means a Line cannot be assigned to a Style - you probably do not need this? So the compiler always statically at compile-time knows, which class an object really is and can call the correct member function. No virtual member functions are needed.
There also were bugs in the draw function, which I corrected below.
The changes to your code are marked with a comment in the following.
// Line.h
#pragma once
#include "Style.h"
#include <vector>
using namespace std;
class Line : private Style // use private inheritance for static polymorphism
{
public:
void draw();
void set_size(int width, int height); // overload set_size (override only for virtual functions)
vector <vector<char>> matrix;
};
// Line.cpp
#include "Line.h"
void Line::set_size(int width, int height)
{
Style::set_size(width, height); // call set_size() function of style
draw(); // draw() to set matrix to new size
}
void Line::draw()
{
Line::matrix.clear(); // clear matrix, if draw() is called more than once
vector <char> row;
int i, j;
for (i = 0; i < Line::height; i++)
{
row.clear();
for (j = 0; j < Line::width; j++) // use Line::width and j++ (there were bugs)
{
row.push_back('-');
}
Line::matrix.push_back(row);
}
}
// Main.cpp
#include <iostream>
#include "Line.h"
using namespace std;
int main()
{
Line line;
line.set_size(10, 10); // calls the enhanced Line::set_size
// The following compilation errors (when the comments are removed) are good, as they prevent wrong usage of the current class definitions
// Style style = line; // would give error, as we have private inheritance and want to prevent 'slicing' and the calling of the wrong member functions; if a Line should be able to be assigned to a Style, you need public dynamic inheritance and virtual functions, as provided in other answers. If you do not need to assign a Line to a Style, use the simpler implementation from this answer.
// Style* stylepointer = &line; // also would give an error
}
Optionally draw() and matrix can be made private in Line.
If you need to call functions (other than set_size) of Style directly, you can use public inheritance, but make all constructors (including default/copy/move) of Style protected, so that only children like Line can call them. This would also prevent assignments of Line to Style.
EDIT: I'm completely changing the original answer since the question was modified too. If I get it right, you would like line.set_size(...) to call first the parent method and then to update the matrix. You cannot do that, because only one method will be called, and not both of them what you could do is add a set_size method for Line that calls Style's one.
line.h should be changed like this:
class Line : public Style
{
public:
void draw();
void set_size(int width, int height);
vector<vector<char>> matrix;
};
and you should append this to line.cpp:
void Line::set_size(int width, int height)
{
// call parent method
Style::set_size(width, height);
// now update matrix
int i, j;
matrix.resize(height);
for (auto &row : matrix)
{
row.resize(width);
}
}
Hope it helps!
Base function must be virtual for runtime inheritance.
as follows example
class base {
public:
virtual void print()
{
cout << "print base class\n";
}
void show()
{
cout << "show base class\n";
}
};
class derived : public base {
public:
void print()
{
cout << "print derived class\n";
}
void show()
{
cout << "show derived class\n";
}
};
int main()
{
base *bptr;
derived d;
bptr = &d;
// Virtual function, binded at runtime
bptr->print();
// Non-virtual function, binded at compile time
bptr->show();
return 0;
}

Towers of Hanoi with Classes

I keep getting the Error C2228 left of '.topDisk' must have class/struct/union and I have no idea what it means, or even how to fix it, even after some research. Is it possible for someone to explain what the error is and how to fix it? I think I've provided you with all the code you need.
HanoiPegClass.cpp File
//A function moving one disk from one peg to another
void moveDisk(Peg& beginning, Peg& destination)
{
assert(beginning.getNumDisks() > 0);
if (destination.getNumDisks() > 0)
{
//Where the error is
assert(beginning.getNumDisks.topDisk() < destination.getNumDisks.topDisk());
}
destination.addDisk(beginning.topDisk());
beginning.removeDisk();
}
Peg.cpp File
//Function to return the disk count (amount of discs on each peg)
unsigned int Peg::getNumDisks()
{
return diskStack.size();
}
//Function to return the value of the top disk
int Peg::topDisk()
{
return diskStack.back();
}
Peg.h File
#pragma once
#include <vector>
#include <string>
using namespace std;
class Peg
{
private:
vector<int> diskStack;
string pegName;
void setName(string name);
public:
Peg(string name, int totalDisks);
unsigned int getNumDisks();
void printDisks();
string getName();
int topDisk();
void addDisk(int totalDisks);
int removeDisk();
~Peg();
};
getNumDisks is a function which returns an unsigned integer, so you cannot use a . on it. You can use the . operator on a structure or class or union only.
So change
assert(beginning.getNumDisks.topDisk() < destination.getNumDisks.topDisk());
to
assert(beginning.topDisk() < destination.topDisk());

C++ error: invalid use of 'AppleFarmer::AppleFarmer' when ca

I am getting the error "error: Invalid use of AppleFarmer::AppleFarmer. I do not know why I am getting this error since I am not trying to pass any input into my Constructor. Is it possible I have an issue with my .h file? What am i doing wrong to get this error?
I have three different files, and I may also be having an issue with linking the code together as I am doing #include for a .cpp file. I am not sure if my code works aside from this error, but I am stuck on this error.
appleFarmerMain.cpp
#include<iostream>
#include "appleFarmer.cpp"
int main(){
AppleFarmer m;
int harvest;
int demand;
m.AppleFarmer();
while(m.endOfMonth()==false){
cout<<"Enter a harvest amount:"<<endl;
cin>>harvest;
m.harvestApples(harvest);
cout<<"Enter a demand:"<<endl;
cin>>demand;
m.sellApples(demand);
cout<<"Apple Inventory: "<<m.getInventory()<<endl;
m.updateCurrentDay();
}
return 0;
}
appleFarmer.cpp
#include "appleFarmer.h"
#include "<iostream>
using namespace std;
AppleFarmer::AppleFarmer(){
for(int i=0;i<30;i++){
sales[i]=0;
harvest[i]=0;
}
}
bool AppleFarmer::sellApples(int demand){
if(demand<= inventory){
sales[currentDay]=demand;
inventory=inventory-demand;
}
else{
sales[currentDay]=0;
}
}
void AppleFarmer::harvestApples(int dayHarvest){
harvest[currentDay]= dayHarvest;
inventory=inventory+dayHarvest;
}
bool AppleFarmer::endOfMonth(){
if (currentDay=maxDays){
return true;
}
else{
return false;
}
}
int AppleFarmer::updateCurrentDay(){
currentDay=currentDay+1;
}
int AppleFarmer::getInventory(){
return inventory;
}
double AppleFarmer::calculateAverageHarvest(){
}
double calculateAverageSales(){
}
void AppleFarmer::printSales(){
}
void AppleFarmer::printHarvest(){
}
appleFarmer.h
#ifndef APPLEFARMER_H
#define APPLEFARMER_H
class AppleFarmer
{
public:
AppleFarmer();
bool sellApples(int);
void harvestApples(int);
bool endOfMonth();
int updateCurrentDay();
int getInventory();
double calculateAverageHarvest();
double calculateAverageSales();
void printSales();
void printHarvest();
private:
int sales[30];
int harvest[30];
int maxDays = 30;
int currentDay = 0;
int inventory = 0;
};
#endif
In C++ you don't call the constructor on an object. That happens at object creation time. The line
m.AppleFarmer();
isn't needed. The constructor is implicitly called here:
AppleFarmer m;
You need to include appleFarmer.h instead of appleFarmer.cpp because the header file (with .h extension) contains the declaration while the .cpp file contains the implementation.
Then you need also to delete m.AppleFarmer(); because the constructor is called during the declaration (AppleFarmer m text line).

How can I create a vector of virtual class?

I'm new to C++, so I decided to work on some little project to improve myself. I try to write a simple chess program with class Unit, and class King which is inherited from Unit
#include <list>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stdlib.h> /* abs */
using namespace std;
// Each unit class represent a chess unit
class Unit{
protected:
int currentX;
int currentY;
string side;
public:
Unit();
Unit(string sideplay, int Xpos,int Ypos)
{
currentX=Xpos; currentY= Ypos;side=sideplay;
}
int getX()
{
return currentX;
}
int getY()
{
return currentY;
}
string getside()
{
return side;
}
void setpos(int newX,int newY) //set new position
{
currentX=newX;
currentY=newY;
}
bool validmove(vector<Unit> unitlist ,string sidepick,int Xpos,int Ypos)
{ int i=0;
while(i != 3)
{ int X=unitlist[i].getX();
int Y=unitlist[i].getY();
string sidetemp= unitlist[i].getside();
if ((X==Xpos)&&(Y==Ypos)&&(sidetemp==sidepick))
{
return false;
}
else if ((X==Xpos)&&(Y==Ypos)&&(sidetemp!=sidepick))
{ //unitlist[i]=NULL;
return true;
}
i++;
}
return true;
}
virtual void moveunit(vector<Unit> unitlist ,int nextX,int nextY);
};
class King: public Unit{
public:
King(string sideplay, int Xpos,int Ypos):Unit(sideplay,Xpos,Ypos)
{}
void moveunit(vector<Unit> unitlist ,int nextX,int nextY){
int diffX=abs(nextX-currentX);
int diffY=abs(nextY-currentY);
if ((diffX==1)||(diffY==1))
{ if (validmove(unitlist,side,nextX,nextY))
{
setpos(nextX,nextY);}
}
}
};
and here is my main:
int main()
{
vector<Unit> chessunit;
chessunit.push_back(King("white",3,1));
chessunit.push_back(King("black",3,2));
chessunit.push_back(King("white",4,1));
if (chessunit[0].validmove(chessunit,"white",3,2))
{
cout<<"hehe"<<endl;
}
chessunit[0].moveunit(chessunit,3,2);
int k= chessunit[0].getY();
cout<<k<<endl;
return 0;
}
I keep getting LNK 2001 error: Unresolved external symbol for my virtual method "moveunit". How can I fix that bug ?
The easiest way of fixing your problem is using pointers or smart pointers: Store vector<Unit*>, vector<std::shared_ptr<Unit>> or vector<std::unique_ptr<Unit>> (thanks #rubenvb) instead of vector<Unit> and then add your kings like so:
myVector.push_back(new King...); // or
myVector.push_back(std::shared_ptr<King>(new King...)); // or
myVector.push_back(std::unique_ptr<King>(new King...));
Why?
If you allocate an object of a virtual class (e.g. Unit unit) and you want to assign an object of an implementation of that class to it, e.g.:
Unit unit;
unit = King(...);
Then you will get an error, or at least run into trouble, unless you provide a constructor for Unit that takes King as an argument or provide a sufficient move operator. That is because if you try to assign an object of a type that is not Unit to unit, the compiler and/or run-time (depending on what the back-end of your compiler is) will have a tough time figuring out how compatible the types are and what to do if things "don't fit" memory-wise and how to cope with memory layout issues.
Further Reading
For more on pointers vs. smart pointers, consider this thread. Also here is a related Stackoverflow question and an article on using shared_ptr with STL collections
More information on trying to "squeeze" an object of one type into another (called slicing) can be found in this thread.
The problem you are facing right now is due to slicing: when you add a King to the vector, it gets sliced into an instance of Unit.
One way to fix this is to turn chessunit into a vector of std::shared_ptr<Unit> and allocate units on the heap.
P.S. Since you are not defining Unit::moveunit(), make it pure virtual:
virtual void moveunit(vector<Unit> unitlist ,int nextX,int nextY) = 0;
^^^

error C2280: attempting to reference a deleted function

I'm new to game development and very new to c++, but I've started developing a little Arkanoid game. I've had it running previously, but after refactoring (introducing the ArkanoidGame class) it doesnt compile and I cannot figure out why.
The error I'm getting is:
d:\dropbox\development\gamedev\c++\arkanoid\arkanoid\main.cpp(14): error C2280:
'ArkanoidGame::ArkanoidGame(void)' : attempting to reference a deleted function
d:\dropbox\development\gamedev\c++\arkanoid\arkanoid\arkanoidgame.h(25) :
compiler has generated 'ArkanoidGame::ArkanoidGame' here
I simply dont understand what this means and have no idea what to do to fix it.
I've included the classes in question:
Main.cpp:
#include "ArkanoidGame.h"
int main() {
ArkanoidGame game;
game.init(800, 600);
while (game.isRunning()) {
game.checkInput();
game.checkCollisions();
game.draw();
}
return 0;
}
Arkanoid.h:
#include "Ball.h"
#include "Pad.h"
#include <SFML/Graphics.hpp>
#include <stdarg.h>
#include <memory>
class ArkanoidGame
{
private:
bool running;
public:
void ArkanoidGame::init(int, int);
bool ArkanoidGame::isRunning();
void ArkanoidGame::checkCollisions();
void ArkanoidGame::checkInput();
void ArkanoidGame::update();
void ArkanoidGame::draw();
sf::RenderWindow* window;
Pad pad;
Ball ball;
};
ArkanoidGame.cpp:
#include "ArkanoidGame.h"
void ArkanoidGame::init(int windowWidth, int windowHeight) {
window = new sf::RenderWindow(sf::VideoMode(windowWidth, windowHeight), "Arkanoid!");
window->setFramerateLimit(60);
ArkanoidGame::running = true;
//Init pad
pad = Pad((float)(windowWidth / 2), (float)(windowHeight - 50));
//Init ball
ball = Ball(0.f, 0.f);
}
template<class T1, class T2> bool intersect(T1& mA, T2& mB) {
return mA.right() >= mB.left() && mA.left() <= mB.right()
&& mA.bottom() >= mB.top() && mA.top() <= mB.bottom();
}
void ArkanoidGame::checkCollisions() {
if (!intersect(pad, ball)) return;
ball.velocity.y = -ball.ballVelocity;
if (ball.x() < pad.x()) {
ball.velocity.x = -ball.ballVelocity;
}
else {
ball.velocity.x = ball.ballVelocity;
}
}
void ArkanoidGame::update() {
//Update positions
pad.update(window->getSize().x);
ball.update(window->getSize().x, window->getSize().y);
}
void ArkanoidGame::draw() {
window->clear(Color::Black);
window->draw(pad.getShape());
window->draw(ball.getShape());
window->display();
}
void ArkanoidGame::checkInput() {
if (Keyboard::isKeyPressed(Keyboard::Key::Escape)) {
running = false;
}
}
bool ArkanoidGame::isRunning() {
return running;
}
Presumably, either Pad or Ball (or both) has no default constructor; therefore one can't be generated for a class that contains them. They must be initialised using one of their declared constructors.
The best solution is to remove your weird init function, and replace it with a constructor:
ArkanoidGame(int windowWidth, int windowHeight) :
running(true),
window(new ...),
Pad(windowWidth / 2, windowHeight - 50),
Ball(0,0)
{
window->setFramerateLimit(60);
}
int main() {
ArkanoidGame game(800, 600);
// ...
}
If you really want a two-stage initialisation dance for some reason, then you'll need to provide default constructors for both Pad and Ball. I wouldn't recommend that though; there's less scope for errors if an object can't be created in an invalid state.
I think that the problem is that either class Pad or class Ball has no the default constructor ( you have two dtat members of these classes in the class definition of ArkanoidGame: Pad pad; and Ball ball;)
. In this case the compiler defined the default constructor of class ArkanoidGame as deleted (otherwise it will be ill-formed). However in the first line of main
ArkanoidGame game;
you try to call the default constructor of class ArkanoidGame.
Take also into account that declarations of member functions shall have unqualified names in the class definition.
So for example this declaration
void ArkanoidGame::init(int, int);
is invalid. Shall be
void init(int, int);
You should provide a constructor for ArkanoidGame. In Arkanoid.h:
ArkanoidGame ();
In Arkanoid.cpp:
ArkanoidGame::ArkanoidGame ()
{
// it is better to initialize members in the constructor,
// although not strictlynecessary
running = false;
}