Facing error in running the programming - c++11

I am trying to run this program, taking vertices of a triangle as inputs.
But i am facing errors. Can someone help me with this ?
What I am trying to do create a point class, inherit in a triangle class and accept the vertices of triangle as inputs.
#include <iostream>
#include <vector>
using namespace std;
#Defines a class Point.
class Point
{
private:
float x;
float y;
public:
int read_Point(Point &P)
{
std::cin >> P.x >> P.y;
}
};
#Defines a class Triangle
class Triangle : public Point
{
private:
std::vector<Point> P;
public:
int make_triangle()
{
P=std::vector<Point>(3);
read_Traingle();
return 0;
}
void read_Traingle()
{
read_Point(P[1]);
read_Point(P[2]);
read_Point(P[3]);
}
};
int main()
{
Triangle Tri;
Tri.make_triangle();
return 0;
}

You initialized the vector with 3 P=std::vector<Point>(3); then you tried to read the element P[3] read_Point(P[3]);
increase the size of vector or read the vector starting with index zero.

Related

Sorting vector of objects c++ raise C2280 error

I have a vector of Workout objects, and I want to sort it by the prices of the workout (each Workout have const field price and getPrice function)
When Im trying to sort the array i get a C2280 error -
Workout &Workout::operator =(const Workout &)': attempting to reference a deleted function
#ifndef WORKOUT_H_
#define WORKOUT_H_
#include <string>
class Workout {
public:
Workout(int w_id, std::string w_name, int w_price, WorkoutType w_type);
int getPrice() const;
Workout& operator =(const Workout& other)
{
if (this == &other) return *this;
return *new(this) Workout(other.getId(), other.getName(),
other.getPrice(), other.getType());
}
private:
const int price;
};
I else have virtual class Customer and cheapCustomer object that inheritence from it, and function- order(const std::vector& workout_options) that needs to sort the vector by the prices.
Here is the Customer cpp file -
#include "Customer.h"
#include <algorithm>
using namespace std;
Customer::Customer(std::string c_name, int c_id) :name(c_name), id(c_id)
{
}
CheapCustomer::CheapCustomer(std::string name, int id) :Customer(name, id)
{
}
std::vector<int> CheapCustomer::order(const std::vector<Workout>& workout_options)
{
std::vector<int>* v = new std::vector<int>();
std::vector<Workout> tmp = workout_options;
std::sort(tmp.begin(), tmp.end(), [](const Workout& w1, const Workout& w2) {
return w1.getPrice() < w2.getPrice();
});
return *v;
//delete v
}
#include <vector>
#include "Customer.h"
#include "Trainer.h"
#include <algorithm>
using namespace std;
int main(int argc, char** argv) {
Workout w1 = Workout(1, "w1", 10, CARDIO);
Workout w2 = Workout(2, "w2", 20, CARDIO);
Workout w3 = Workout(3, "w3", 30, MIXED)
std::vector<Workout> v;
v.push_back(w1);
v.push_back(w2);
v.push_back(w3);
Customer* c_cheap = new CheapCustomer("Cheap", 20);
vector<int> order_cheap = c_cheap->order(v);
can some one please tell me how to fix it?
Thank you so much
I tried to use unique_ptr and still the same error-
C2280 'std::unique_ptr<Workout,std::default_delete>::unique_ptr(const std::unique_ptr<Workout,std::default_delete> &)': attempting to reference a deleted function
std::vector<int> CheapCustomer::order(const std::vector<Workout>& workout_options)
{
vector<int>* v = new std::vector<int>();
vector<unique_ptr<Workout>> v_unique_ptr;
for (Workout workout : workout_options) {
v_unique_ptr.push_back(unique_ptr<Workout>(new Workout(workout.getId(),workout.getName(),workout.getPrice(),workout.getType())));
}
std::sort(v_unique_ptr.begin(), v_unique_ptr.end(), [](unique_ptr<Workout> w1, unique_ptr<Workout> w2) {
return w1->getPrice() < w2->getPrice();
});
}
Edited:
its worked here
vector<int>* v = new std::vector<int>();
vector<unique_ptr<Workout>> v_unique_ptr;
for (Workout workout : workout_options) {
v_unique_ptr.push_back(move(unique_ptr<Workout>(new Workout(workout.getId(),workout.getName(),workout.getPrice(),workout.getType()))));
}
std::sort(v_unique_ptr.begin(), v_unique_ptr.end(), [](unique_ptr<Workout>& w1, unique_ptr<Workout>& w2) {
return w1->getPrice() < w2->getPrice();
});
v->push_back(v_unique_ptr[0]->getId());
return *v;
Thank you so much
In order to use std::sort, the element type needs to be move-assignable. Your element type isn't, because of all the const data members.
So you may either:
Remove the const
Provide your own move assignment operator that somehow gets around const
Don't place Workout objects in a container, place pointers instead (preferably smart pointers such as unique_ptr).

Flowchart for function overloding

How we can draw flowchart and algorithm for function overloading
#include<iostream>
using namespace std;
int area(int);
int area(int,int);
float area(float);
float area(float,float);
Main function here
int main()
{
int s,l,b;
float r,bs,ht;
cout<<"Enter side of a
square:";
cin>>s;
cout<<"Enter length and
breadth of rectangle:";
cin>>l>>b;
cout<<"Enter radius of
circle:";
cin>>r;
cout<<"Enter base and height of triangle:";
cin>>bs>>ht;
cout<<"Area of square is"<<area(s);
cout<<"\nArea of rectangle is "<<area(l,b);
cout<<"\nArea of circle is "<<area(r);
cout<<"\nArea of triangle is "<<area(bs,ht);
}
For square
int area(int s)
{
return(s*s);
}
For rectangle
int area(int l,int b)
{
return(l*b);
}
For circle
float area(float r)
{
return(3.14*r*r);
}
For trianle
float area(float bs,float
ht)
{
return((bs*ht)/2);
}
It is possible to draw flowchart and algorithm for this program

How to use a Manager class to manage Characters and their animations in C++ using the SFML library

I'm trying to create a 2D sidescroller mini-game. For now, I only have a character with a sprite and one animation, which i'm trying to move using the left/right arrows. At first, I only had a Character class, storing the sprite of the character and its running animation. And it worked. But now, I'm trying to add a CharacterManager class, which will create all the characters to avoid doing it in the main, and which will manage their movements and draw them.
And it doesn't work anymore. I think my problems come from the fact that I have trouble using pointers, which I'm not really familiar with.
Here are the different classes I'm using :
Animation.h :
#pragma once
#include <vector>
#include <SFML/Graphics.hpp>
#include <stdexcept>
#include <ctime>
#include "Constants.h"
class Animation {
public:
Animation();
~Animation();
void SetFrames(std::vector<sf::IntRect> frames) { m_frames = frames; }
sf::IntRect Play();
private:
std::vector<sf::IntRect> m_frames;
unsigned int m_currentFrame;
float m_updateTime;
float m_timeSinceLastFrame;
float m_lastCallTimestamp;
float m_currentTimestamp;
bool m_firstCall;
};
Animation.cpp :
#include "Animation.h"
Animation::Animation() {
m_currentFrame = 0;
m_updateTime = 1.0f / ANIMATION_SPEED;
m_timeSinceLastFrame = 0.0f;
m_firstCall = true;
}
Animation::~Animation() {
}
sf::IntRect Animation::Play() {
if (m_frames.size() == 0) {
throw std::length_error("The frames vector is empty");
}
// Advance time and add the elapsed time to timeSinceLastFrame
m_currentTimestamp = std::clock();
// Ignore elapsed time if first call
if (m_firstCall) {
m_timeSinceLastFrame = 0.0f;
m_lastCallTimestamp = m_currentTimestamp;
m_firstCall = false; // Not first call anymore
}
else {
m_timeSinceLastFrame += (m_currentTimestamp - m_lastCallTimestamp) / CLOCKS_PER_SEC;
m_lastCallTimestamp = m_currentTimestamp;
}
// Next frame
if (m_timeSinceLastFrame >= m_updateTime) {
m_currentFrame++;
m_timeSinceLastFrame = 0;
// Check animation end
if (m_currentFrame >= m_frames.size()) {
m_currentFrame = 0; // Reset frame progression
m_firstCall = true; // Next passage will be the first call of a new animation
/* TODO : return something to alert the end of the animation
(like a specific rectint or set a variable to true and get it on the other side) */
}
}
return m_frames[m_currentFrame];
}
Character.h :
#pragma once
#include<string>
#include<iostream>
#include <SFML/Graphics.hpp>
#include <vector>
#include <map>
#include "Constants.h"
#include "Animation.h"
class Character : public sf::Drawable {
public:
Character();
Character(std::string name);
~Character();
void Move(float value);
// Setters
void SetTexture(std::string filename);
void SetPosition(sf::Vector2f pos) { m_position = pos; };
void SetAnimations(std::map<std::string, Animation*> animations) { m_animations = animations; };
protected:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
std::string m_name;
unsigned int m_orientation; // 0 (default) = right | 1 = left
std::map<std::string, Animation*> m_animations;
Animation runningAnimation;
sf::Vector2f m_position;
sf::Texture m_texture;
sf::Sprite m_sprite;
};
Character.cpp :
#include "Character.h"
Character::Character() {}
Character::Character(std::string name) {
m_name = name;
m_orientation = 0;
runningAnimation = Animation();
}
Character::~Character() {
}
void Character::draw(sf::RenderTarget& target, sf::RenderStates states) const {
target.draw(m_sprite, states);
}
void Character::Move(float value) {
m_sprite.setTextureRect(runningAnimation.Play());
m_position.x += value;
m_sprite.setPosition(m_position);
}
void Character::SetTexture(std::string filename) {
filename = TEXTURE_FILES_PREFIX + filename;
// Load the entire texture file
if (!m_texture.loadFromFile(filename))
std::cout << "Error loading texture file : " << filename << std::endl;
// Set the texture (by default, initialize to idle state) and the position
std::vector<sf::IntRect> runningFrames{
sf::IntRect(67, 45, 19, 28),
sf::IntRect(116, 46, 20, 27),
sf::IntRect(166, 48, 20, 25),
sf::IntRect(217, 45, 22, 28),
sf::IntRect(266, 46, 19, 27),
sf::IntRect(316, 48, 20, 25)
};
runningAnimation.SetFrames(runningFrames);
m_sprite.setTexture(m_texture);
m_sprite.setTextureRect(runningAnimation.Play());
m_sprite.setPosition(m_position);
}
CharacterManager.h :
#pragma once
#include <vector>
#include <map>
#include <iostream>
#include <SFML\Graphics.hpp>
#include "AliveCharacter.h"
#include "Npc.h"
#include "Animation.h"
#include "CharacterStats.h"
enum CharacterType
{
NPC,
ALIVE,
GENERAL
};
// Class containing a vector of character entities and creates the animations of these entities from a data file (later)
class CharacterManager : public sf::Drawable {
public :
CharacterManager();
~CharacterManager();
// Loads the file and stores the content inside data string (not used for now)
void LoadDataFile(std::string filename);
// Create a character and add it to the list
void CreateCharacter(std::string name, std::string textureFilename, CharacterType characterType, sf::Vector2f pos);
void CreateCharacter(std::string name, std::string textureFilename, CharacterType characterType, sf::Vector2f pos, std::map<std::string, Animation*> animations);
void CreateCharacter(std::string name, std::string textureFilename, CharacterType characterType, sf::Vector2f pos, std::map<std::string, Animation*> animations, CharacterStats stats);
void Move(float value);
Character* GetCharacter(std::string name) { return m_characters[name]; }
private :
// Calls the draw() function of each stored Character
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
std::string m_data;
std::map<std::string, Character*> m_characters;
};
CharacterManager.cpp :
#include "CharacterManager.h"
CharacterManager::CharacterManager() {
m_characters = std::map<std::string, Character*>();
}
CharacterManager::~CharacterManager() {
//delete m_characters;
}
void CharacterManager::LoadDataFile(std::string filename) {
// TODO : load file content
}
void CharacterManager::CreateCharacter(std::string name, std::string textureFilename, CharacterType characterType, sf::Vector2f pos) {
Character new_character(name); // Create a generic character...
// ... and specialise it depending on the character type param
switch (characterType)
{
case NPC:
new_character = Npc(name);
break;
case ALIVE:
new_character = AliveCharacter(name);
break;
default:
new_character = Character(name);
break;
}
// Set texture, position and add to the characters list
new_character.SetTexture(textureFilename);
new_character.SetPosition(pos);
m_characters.insert({ name, &new_character });
}
void CharacterManager::CreateCharacter(std::string name, std::string textureFilename, CharacterType characterType, sf::Vector2f pos, std::map<std::string, Animation*> animations) {
CreateCharacter(textureFilename, name, characterType, pos);
m_characters[name]->SetAnimations(animations);
}
void CharacterManager::CreateCharacter(std::string name, std::string textureFilename, CharacterType characterType, sf::Vector2f pos, std::map<std::string, Animation*> animations, CharacterStats stats) {
CreateCharacter(textureFilename, name, characterType, pos);
m_characters[name]->SetAnimations(animations);
//m_characters[name]->SetStats(stats);
}
void CharacterManager::Move(float value) {
for each (std::pair<std::string, Character*> pair in m_characters) {
Character* character = pair.second;
character->Move(value);
}
}
void CharacterManager::draw(sf::RenderTarget& target, sf::RenderStates states) const {
for each (std::pair<std::string, Character*> pair in m_characters) {
Character* character = pair.second;
target.draw(*character);
}
}
And finally the Main.cpp, where you can see in comments the things I tried without success :
#include "Map.h"
#include "CharacterManager.h"
int main()
{
sf::RenderWindow window(sf::VideoMode(WINDOW_SIZE_X, WINDOW_SIZE_Y), WINDOW_TITLE);
window.setFramerateLimit(WINDOW_FRAMERATE);
Map map;
int pos = WINDOW_SIZE_X / 2 - MAP_SIZE_X / 2;
float movement = 0;
map.SetPosition(pos);
map.SetGroundTexture("Foreground/Tileset.png");
map.SetBackgroundTexture("Background/BGFront.png");
CharacterManager charManager;
charManager.CreateCharacter("main", "Characters/test-character.png", ALIVE, sf::Vector2f(400, WINDOW_SIZE_Y - HEIGHT_OF_GROUND - 28));
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Left)
movement = -MOVING_SPEED;
else if (event.key.code == sf::Keyboard::Right)
movement = MOVING_SPEED;
}
else if (event.type == sf::Event::KeyReleased)
movement = 0;
}
// Move the map
map.Scroll(movement);
//charManager.GetCharacter("main")->Move(movement);
charManager.Move(movement);
window.clear();
window.draw(map);
/*Character* mainPerso = charManager.GetCharacter("main");
window.draw(*mainPerso);*/
window.draw(charManager);
window.display();
}
return 0;
}
The error I'm getting is on the return m_frames[m_currentFrame] line in Animation.cpp, in the end of the Play() function. A pop-up window opens saying : "Expression: vector subscript out of range". This error only happens the second time the code goes through this line. The first time it's called from the SetTexture() function of Character.cpp (m_sprite.setTextureRect(runningAnimation.Play())), itself called from the CreateCharacter() function of the CharacterManager (new_character.SetTexture(textureFilename)), and at this point the Animation object looks as it should.
But the second time, it's called from the Move() function of Character (m_sprite.setTextureRect(runningAnimation.Play())), itself called from the Move() function of the CharacterManager (character->Move(value)). And at this point, all of the Animation object absolutely doesn't look like it should. In debug mode, I can see this :
Debug screenshot
As I said earlier, I think the problem comes from the use of pointers. When I'm trying to remove them, the code runs, but I get a white square problem.
I tried to find some sort of tutorial on how to use this kind of architecture, but didn't find anything relevant. If you know one, I'll be glad to look at it.
As I said earlier, I think the problem comes from the use of pointers.
When I'm trying to remove them, the code runs, but I get a white
square problem.
yep, it is a common issue for SFML when using Texture and Sprite when shallow copy is used.
Let's look at sf::Sprite::setTexture reference:
The texture argument refers to a texture that must exist as long as
the sprite uses it. Indeed, the sprite doesn't store its own copy of
the texture, but rather keeps a pointer to the one that you passed to
this function. If the source texture is destroyed and the sprite tries
to use it, the behavior is undefined.
So, a class like below, with default generated copy operation by compiler:
class Foo {
public:
void setT() {
// generate texture {t}
s.setTexture(t);
}
sf::Sprite s;
sf::Texture t;
};
will bring troubles to you. Because when a copy is made by Foo f(otherFoo);, sprite in newly created instance of Foo will have pointer to texture of otherFoo - it is shallow copy of pointer to sf::Texture. Deleting otherFoo will make a dangle pointer inside new constructed object.
In this case, you should implement assignment operation which makes deep copy of texture for sprite. If you don't know how to do it, you should mark assignment operations as deleted:
class Character : public sf::Drawable {
public:
Character();
Character(std::string name);
~Character();
// added
Character& operator=(const Character&) = delete;
Character(const Character&) = delete;
void Move(float value);
Then, compiler will give you an error for each attempt of copying of Character instance.
In case of deleted copy operation, you should rely on pointers. Your attempt failed, because you store pointer to local variables. Local variables are deleted at the end of a function scope, and referring to them later is undefined behaviour.
You have to create Character by operator new:
void CharacterManager::CreateCharacter(std::string name, std::string textureFilename, CharacterType characterType, sf::Vector2f pos) {
Character* new_character = new Character(name); // Create a generic character...
//...
// Set texture, position and add to the characters list
new_character->SetTexture(textureFilename);
new_character->SetPosition(pos);
m_characters.insert({ name, new_character });
}

Why is this code working in a different way than expected? I think its working right, is it?

Here is what I am supposed to do.
Here is what I did.(on codeblocks IDE with minGW compiler)
#include <iostream>
using namespace std;
class person
{
private:
string name;
int age;
double height;
double weight;
public:
void set_private_members(string n, int a, double h, double w)
{
name = n;
age = a;
weight = h;
height = w;
}
void print_private_members()
{
cout <<"The name of person is:- "<<name<<"\n The age of person is:- " <<age<<"\n The weight of person is:- "<<weight;
cout <<"\n The height of person is:- "<<height<<endl;
}
};
void modify_person(person);
int main()
{
person p;
p.set_private_members("Ayush",19,165.7,47.2);
cout <<"We are in main function right now \n";
p.print_private_members();
modify_person(p);
cout <<"We are now back in main function \n The values of object passed to modify_person function are as \n";
p.print_private_members();
return 0;
}
void modify_person(person z)
{
cout <<"We are in modify_person function \n Modifying person details... \n";
z.set_private_members("Priyanshi",15,159.1,50.6);
cout <<"The details are now as:- \n";
z.print_private_members();
}
Here is the output to this code
however the expected output is to have priyanshi details in the class object when print_private_members function is called in main() for the last time.
Who is wrong? Me or they? I think if I call modify_person by reference then the expected should come.

Run time error in graph

I am implementing Graph for the first time and for that I took this problem from SPOJ.
Took help of geeksforgeeks, applied union find algorithm to find out whether or not graph contains a cycle but I get run time error (SIGSEGV).
Can you please help why is it so?
#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
struct Edge{
int s,d;
};
struct Graph{
int v,e;
struct Edge* edge;
};
struct Graph* create(int v, int e){
struct Graph* graph=(struct Graph*)malloc(sizeof (struct Graph));
graph->v=v;
graph->e=e;
graph->edge=(struct Edge*)malloc(sizeof (struct Edge));
return graph;
};
int Find(int p[],int i)
{
if (p[i] == -1)
return i;
return Find(p, p[i]);
}
void Union(int p[],int i, int j)
{
p[j]=i;
}
bool CheckCycle(struct Graph* graph)
{
int *p=(int*)malloc(graph->v* sizeof (int));
memset(p,-1,graph->v * sizeof (int));
/*for(int i=0;i<graph->v;i++)
cout<<"p"<<i<<"="<<p[i];
cout<<"\n";*/
for(int i=0;i<graph->e;i++)
{
/*cout<<"edge"<<i<<" src="<<graph->edge[i].s<<"\n";
cout<<"edge"<<i<<" dest="<<graph->edge[i].d<<"\n";*/
int x=Find(p,graph->edge[i].s);
int y=Find(p,graph->edge[i].d);
/*cout<<"x="<<x<<" "<<"y="<<y<<"\n";*/
if(x==y)
return true;
Union(p,x,y);
}
return false;
}
int main()
{
ios_base::sync_with_stdio(false);
int N,M,v1,v2;
cin>>N>>M;
if(M!=(N-1))
cout<<"NO\n";
else{
struct Graph* graph=create(N,M);
for(int i=0;i<M;i++)
{
cin>>v1;
graph->edge[i].s=v1-1;
cin>>v2;
graph->edge[i].d=v2-1;
}
if(CheckCycle(graph))
cout<<"NO\n";
else
cout<<"YES\n";
}
}
One issue is this in your main program:
graph->edge[i].s=v1-1;
You created a single edge. If i is greater than 0, then this is an out-of-bounds access.
Look how you created edge in the create function:
graph->edge=(struct Edge*)malloc(sizeof (struct Edge));
That allocation holds a single edge, not multiple edges. Given how you coded the rest of your program in a C-like fashion, what you probably wanted is this:
graph->edge=(struct Edge*)malloc(sizeof(Edge) * e);
Also, you should strive to not use single-letter variable names. It is hard to read code with e, v, etc. as member variable names. Name those items m_edge, m_vertex or something that is more descriptive.

Resources