Cannot create constructor with std::array<T, n> as class member - c++

Here the code
#include "card.h"
#include <array>
constexpr int DECK_SIZE = 52;
class Deck {
std::array<Card, DECK_SIZE> m_deck;
public:
Deck();
~Deck() = default;
Card getCard(int index) { return m_deck[index]; }
};
Card is just another class, not relevant here.
I want to create Deck constructor now, which will just create 52 Card objects and assign it to my array. Although, when I go to Deck.cpp and start doing this
#include "deck.h"
Deck::Deck() {
}
I got error that I reference deleted function
'std::array::array(void)': attempting to reference a deleted
function
I dont really understand, array size is known at compile time, now I just want to create objects and assign it to this array, why I cant do that?
Didnt realize that Card is actaully relevant in this case, anyways here is the code
#include <SFML/Graphics.hpp>
constexpr auto FILE_PATH = "res\\cards\\";
class Card {
char m_rank;
char m_suit;
int m_value;
sf::RectangleShape m_shape;
sf::Texture m_texture;
public:
Card(char, char, int, std::string);
~Card() = default;
char getRank() { return m_rank; }
char getSuit() { return m_suit; }
int getValue() { return m_value; }
void setValue(int p_value) { m_value = p_value; }
sf::Texture getTexture() { return m_texture; }
sf::RectangleShape getShape() { return m_shape; }
void setPosition(float p_x, float p_y) { m_shape.setPosition(p_x, p_y); }
};
Card::Card(char p_rank, char p_suit, int p_value, std::string p_texture_file_name)
:m_rank(p_rank), m_suit(p_suit), m_value(p_value) {
m_texture.loadFromFile(FILE_PATH + p_texture_file_name);
m_shape.setSize((sf::Vector2f(70, 90)));
m_shape.setTexture(&m_texture);
}

In order to default-construct std::array<Card, DECK_SIZE>, Card must be default-constructible. Your Card class is not.

Related

How to instantiate abstract child class with parent class

I'm trying to make a Chess game, and I'm having difficulties with creating the objects. My thought process went something like this:
Create a game board with 64 tiles, the tiles would have their own position and a pointer to a piece, thus I would be able to "easily" load in and unload a piece.
Tile class:
class Tile {
private:
int x;
int y;
Piece* piece;
public:
Tile(int x, int y) {
this->x = x;
this->y = y;
piece = nullptr;
}
void loadTile(Piece piece) {
this->piece = new Piece(piece); //this gives an error
}
void unloadTile() {
delete this->piece;
}
};
The individual pieces would then inherit from a parent class (below you can see a dumbed-down version). Inherited pieces would all have the same constructor and they would only differ in the way they calculate the possible moves. This, in my mind, is the best scenario to use a virtual function.
Piece and pawn class:
class Piece {
protected:
int x;
int y;
public:
Piece(int x, int y) {
this->x = x;
this->y = y;
}
virtual vector<int> returnPossibleMoves() = 0;
};
class Pawn : public Piece {
public:
using Piece::Piece;
vector<int> returnPossibleMoves() {
vector<int> moves;
moves.push_back(10); //dont think about this too much
return moves;
}
};
And here is the problem - the loadTile() function cannot instantiate the piece object because it is abstract.
I can see that my code may not work because I try to instantiate Piece with Pawn, but I don't really know how I would make it work, or what the workaround for this is. Hopefully you will be able to see what I'm trying to go for.
To strictly answer the question: you cannot create instances of abstract classes. That's why new Piece is not allowed. You would have to create an instance of a derived type that is not abstract, such as Pawn, and assign the piece pointer to point to that:
void Tile::loadTile() {
this->piece = new Pawn; //this is allowed
}
There are clearly some design changes that you'll need to make with this in mind, some of which have been mentioned in the comments on your question.
The Tile don't know which Piece type to instantiate, this is the fundamental problem.
What about something like this? (Disclaim, I just implemented some ideas, the code need probably lot of improvements until to get to sufficient quality)
#include <array>
#include <cassert>
#include <memory>
#include <vector>
using namespace std;
class Piece;
using CPiecePtr = std::shared_ptr<const Piece>;
enum class PieceType
{
Pawn
};
class Pos
{
int m_x=0;
int m_y=0;
public:
Pos()=default;
Pos(const Pos&)=default;
Pos& operator=(const Pos&)=default;
Pos( int x, int y): m_x(x), m_y(y)
{
assert(x>=0 && x<8 && y>=0 && y<8);
}
int x() const { return m_x; }
int y() const { return m_y; }
};
class Move
{
Pos m_origin;
Pos m_destination;
public:
Move()=default;
Move(const Move&)=default;
Move& operator=(const Move&)=default;
Move( const Pos& orig, const Pos& dest): m_origin(orig), m_destination(dest){}
const Pos& getDestination() const { return m_destination; }
const Pos& getOrigin() const { return m_origin; }
};
using MoveSet = std::vector<Move>;
class Tile
{
private:
CPiecePtr m_piece;
public:
void loadTile(CPiecePtr piece)
{
m_piece = piece;
}
void unloadTile()
{
m_piece = nullptr;
}
void setPiece(CPiecePtr piece) // this is more generic than previous two functions
{
m_piece = piece;
}
CPiecePtr getPiece() const
{
return m_piece;
}
};
class Piece
{
PieceType m_type;
public:
virtual MoveSet returnPossibleMoves(const Pos&) const = 0;
Piece(): m_type(PieceType::Pawn){}
PieceType getType() const { return m_type; }
};
class Pawn : public Piece
{
public:
MoveSet returnPossibleMoves(const Pos& pos) const override
{
MoveSet moves;
moves.push_back(Move(pos, Pos(pos.x(), pos.y()+1)));
//...
//TODO how to manage special moves? King-rook, replace pawn at end line...
return moves;
}
};
class Chess
{
private:
std::array<std::array<Tile,8>,8> m_board;
std::vector<CPiecePtr> m_pieces;
public:
Chess()
{
m_pieces.push_back( std::make_shared<const Pawn>());
//...
setPieceAt(Pos(0,1), m_pieces[0]);
}
CPiecePtr getPieceAt( const Pos& pos) const
{
return m_board[pos.x()][pos.y()].getPiece();
}
void setPieceAt( const Pos& pos, CPiecePtr piece)
{
return m_board[pos.x()][pos.y()].setPiece(piece);
}
// example:
MoveSet getMoveSetForPos( const Pos& pos)
{
const auto& piecePtr = getPieceAt(pos);
if (nullptr != piecePtr)
{
return piecePtr->returnPossibleMoves(pos);
}
return {};
}
void movePiece( const Move& move)
{
const auto& prevPiece = getPieceAt(move.getOrigin());
const auto& nextPiece = getPieceAt(move.getDestination());
assert(prevPiece && !nextPiece);
setPieceAt(move.getDestination(), prevPiece);
setPieceAt(move.getOrigin(), nullptr);
}
};
int main()
{
Chess chess;
const auto& moves = chess.getMoveSetForPos(Pos(0,1));
if (moves.size()>0)
{
chess.movePiece(moves[0]);
}
assert( chess.getPieceAt(Pos(0,2))->getType() == PieceType::Pawn);
return 0;
}
EDIT: I was not very proud of the answer, so I edited the code to make it compile. However, a fully working Chess is more complex than that, I leave how to manage king-rook and other special moves to the reader.

"Call to implicitly deleted default constructor of "error

I keep getting three errors that all relate to "Call to implicitly deleted default constructor of ____. Would anyone happen to know why this is?
/Users/vivekreddy/Desktop/Vivek/School/Spring 2016/CS32/project 3/project 3/Player.cpp:114:18: Call to implicitly-deleted default constructor of 'BadPlayerImpl'
#include "provided.h"
#include <iostream>
#include <string>
using namespace std;
class HumanPlayerImpl:public Player
{
public:
virtual bool isInteractive() const { return true;};
int chooseMove(const Scaffold& s, int N, int color);
};
class BadPlayerImpl: public Player
{
public:
int chooseMove(const Scaffold& s, int N, int color);
};
class SmartPlayerImpl: public Player
{
public:
virtual bool isInteractive() const { return true;};
int chooseMove(const Scaffold& s, int N, int color);
};
//implementations
//put virtual in front of implementations only or declarations here as well?
int HumanPlayerImpl::chooseMove(const Scaffold& s, int N, int color) //goal is to get N in a row, return the column necessary to put the checker so we could do that. otherwise return -1. can make the column be arbitrary
{
//algorithm is inputting N so maybe don't need this check?
if (N>s.cols()||N<=0) {
cout<<"Enter a number within the valid range of columns you specified";
return -1;
}
if(s.numberEmpty()==0)
{
return -1;
}
int columnnum;
while (columnnum<=s.cols()||columnnum<=0) {
cout<<"Enter column number of your move";
cin>>columnnum;
if (columnnum<=s.cols()) {
return columnnum;
}
cout<<"Column number not valid ";
}
return -1; //OK?
}
int BadPlayerImpl::chooseMove(const Scaffold& s, int N, int color)
{
if ((N>=s.cols()&&N>=s.levels())||N<=0) { //make sure this works
cout<<"Enter a number within the valid range of columns you specified";
return -1;
}
for (int j=0; j<s.cols();j++) {
if (s.checkerAt(j,0)==VACANT) {
return j;
}
}
return -1; //see if this OK
}
int SmartPlayerImpl::chooseMove(const Scaffold& s, int N, int color)
{
return -1; // This is not always correct; it's just here to compile
}
//******************** Player derived class functions *************************
// These functions simply delegate to the Impl classes' functions.
// You probably don't want to change any of this code.
HumanPlayer::HumanPlayer(string nm)
: Player(nm)
{
m_impl = new HumanPlayerImpl; //error is here
}
HumanPlayer::~HumanPlayer()
{
delete m_impl;
}
int HumanPlayer::chooseMove(const Scaffold& s, int N, int color)
{
return m_impl->chooseMove(s, N, color);
}
BadPlayer::BadPlayer(string nm)
: Player(nm)
{
m_impl = new BadPlayerImpl; //error is here
}
BadPlayer::~BadPlayer()
{
delete m_impl;
}
int BadPlayer::chooseMove(const Scaffold& s, int N, int color)
{
return m_impl->chooseMove(s, N, color);
}
SmartPlayer::SmartPlayer(string nm)
: Player(nm)
{
m_impl = new SmartPlayerImpl; //error is here
}
SmartPlayer::~SmartPlayer()
{
delete m_impl;
}
int SmartPlayer::chooseMove(const Scaffold& s, int N, int color)
{
return m_impl->chooseMove(s, N, color);
}
Below is my declaration of the class Player which is the base class:
class Player
{
public:
Player(std::string nm) : m_name(nm) {}
virtual ~Player() {};
std::string name() const { return m_name; };
virtual bool isInteractive() const { return false; }
virtual int chooseMove(const Scaffold& s, int N, int color) = 0;
// We prevent any kind of Player object from being copied or assigned by
// making the copy constructor and assignment operator unavailable in
// the base class (and thus in any derived class).
Player(const Player& other) = delete;
Player& operator=(const Player& other) = delete;
private:
std::string m_name;
};
Because you declared a constructor in your base class, in particular Player::Player(std::string nm), it's impossible for the compiler to provide an implicit default constructor for your child class as your parent class Player can't be default constructed in the first place.
Either provide a constructor in your child class or inherit the constructor of your base class (C++11). E.g:
BadPlayerImpl::BadPlayerImpl(std:string nm)
: Player(nm)
{
...
}
This is most likely because somewhere in your code you are copy-constructing, or assigning to, an instance of BadPlayerImpl, and you explicitly deleted the copy constructor and the assignment operator of its superclass.
A default constructor is normally automatically created for a class, but there are rules about when it is not created (like when you create another constructor). Where you have "//error is here" you're calling the default constructor of a Sub-Class which will call the (in this case, non-existent) default constructor of the Base-Class.

Class factory to create derived classes c++

I'm currently learning about class factory patterns with C++. I keep having errors while trying to implement the factory. Suppose I have an abstract class and two derived classes. What I want the factory to do is to create a new object of the base class like so: Ball *sc = new SoccerBall();
I am not sure on how to implement this, I have tried but of no avail. What do I need to fix?
class Ball
{
public:
Ball();
virtual ~Ball();
virtual int getSize() const = 0;
virtual void setBallSize(int s) = 0;
virtual string ballManufacturer() const = 0;
protected:
int ballSize;
}
class Soccerball:public Ball
{
public:
Soccerball();
Soccerball(int size);
~Soccerball();
int getSize() const;
void setBallSize(int s);
string ballManufacturer() const;
}
class Soccerball:public Ball
{
public:
Soccerball();
Soccerball(int size);
~Soccerball();
int getSize() const;
void setBallSize(int s);
string ballManufacturer() const;
}
class Basketball:public Ball
{
public:
Basketball();
Basketball(int size);
~Basketball();
int getSize() const;
void setBallSize(int s);
string ballManufacturer() const;
}
class BallFactory
{
public:
Ball* createBall(string s)
{
if(s == "Soccer")
{
return new Soccerball(5);
}
if(s == "Basket")
{
return new Basketball(6);
}
}
}
This how your code will work, but above when you are posting a question you should provide "Short Self Contained Correct Code" and make easy for people to understand your problem easily.
#include <iostream>
using namespace std;
class Ball
{
public:
Ball()
{
cout<<"Ball ctr"<<endl;
}
virtual ~Ball()
{
}
virtual int getSize() const = 0;
virtual void setBallSize(int s) = 0;
virtual string ballManufacturer() const = 0;
protected:
int ballSize;
};
class Soccerball:public Ball
{
public:
Soccerball()
{
cout<<"create Default Soccer Ball "<<endl;
}
Soccerball(int size)
{
cout<<"create Soccer Ball "<<size<<endl;
}
~Soccerball()
{
}
int getSize() const
{
return ballSize;
}
void setBallSize(int s)
{
ballSize = s;
}
string ballManufacturer() const
{
return "";
}
};
class Basketball:public Ball
{
public:
Basketball()
{
cout<<"create default Baseket Ball "<<endl;
}
Basketball(int size)
{
cout<<"create Baseket Ball "<<size<<endl;
}
~Basketball()
{
}
int getSize() const
{
return ballSize;
}
void setBallSize(int s)
{
ballSize = s;
}
string ballManufacturer() const
{
return "";
}
};
class BallFactory
{
public:
//Factory method
static Ball* createBall(string s)
{
if(s == "Soccer")
{
return new Soccerball(5);
}
if(s == "Basket")
{
return new Basketball(6);
}
}
};
int main()
{
Ball* ptr = BallFactory::createBall("Soccer");
return 0;
}
But you also need to understand how Factory design pattern works and how a namesake virtual constructor is created and why you would use a parameterized factory. Or could you use a template factory.

Creating List Like Array with Dynamic Memory Management

There are a lecture class and student class. We are trying to save student information on lecture class with arrays.
For example:
Student * studentList = new Student[numberOfStudent];
studentAdd("Mary");
studentDelete("Mary");
Problem:
User is not giving number of student and number of student is increasing when user add a new one with a one of lecture method. So I think that i need a list like structer to save them but it is forbidden for this work. Do you have any efficient ideas than my temporary solution?
My temporary solution:
Saving number of student and array size and when number of student is more than size copy array to a new one which is bigger than old one.
This question is related to my assigment which we are forcing to this by
*using dynamically allocated memory using pointers
*without using any static arrays with fixed sizes or other data structures such as
vector from the standard library
you could just use functions if you don't want to use objects. Note that I haven't compiled this code.
#include <iostream>
#include <sstream>
#include <string>
#include "Student.h"
void add(Student **list, Student *rhs);
void destroy(Student **list,int const &idx);
void destroy(Student **list,const char* student_name); //find the student name and delete
void resize(Student **list,int const &idx);
Student** begin(Student **list,); //get the first Student
Student** end(Student **list,); //the end of the array
void clear(Student **list,); //drop all Students
int main(int argc, char **argv)
{
if(argc < 2)
{
stc::cerr << "not enough parameters" << std::endl;
}
istringstream buffer(argv[1]);
int value;
buffer >> value;
Student ** studentList = new *Student[value];
int s
add(studentList, "Mary");
destroy(studentList, "Mary");
return(0);
}
void add(Student **list, Student *rhs) { /*definition*/ }
void destroy(Student **list, int const &idx) { /*definition*/ }
void destroy(Student **list, const char* student_name) { /*definition*/ }
void resize(Student **list, int const &idx) { /*definition*/ }
Student** begin(Student **list) { /*definition*/ }
Student** end(Student **list) { /*definition*/ }
void clear(Student **list) { /*definition*/ }
Now just define all that and you are all set
I do not recommend this approach
I would use objects... and taking into account what PaulMcKenzie said about capacity
class StudentList
{
private:
Student **list;
std::size_t size;
std::size_t capacity;
public:
StudentList(){}
~StudentList(){ this->clear(); }
inline void add(Student *rhs) { //definition }
inline void destroy(int const &idx) { //definition }
inline void destroy(const char* student_name) { //definition }
inline void resize(int const &idx) { //definition }
inline Student** begin() { //definition }
inline Student** end() { //definition }
inline void clear() { //definition }
};
And if possible
Iterators
Underneath vector you will find a similar implementation, it uses Iterators to encapsulate the Student**.

Hash Table not accepting function passed into constructor in member init list

I have a hash table template that I have written for a class. I have a project due that relies on utilizing this hash table. It accepts an unsigned integer value to initialize the number of buckets it has, as well as a hash function to point to. I have not written that hash function yet, but I have a declaration for it. When I try to use the member initializer in my Game class for the hash table data member, it gives me an error that I don't understand.
Error 1 error C3867: 'Game::xorHash': function call missing argument list; use '&Game::xorHash' to create a pointer to member
2 IntelliSense: no instance of constructor "HTable<Type>::HTable [with Type=std::string]" matches the argument list
argument types are: (int, unsigned int (const std::string &s))
my Hash Table class is as follows:
#pragma once
#include "SLList.h"
template<typename Type> class HTable
{
public:
HTable(unsigned int numOfBuckets, unsigned int (*hFunction) (const Type &v));
~HTable();
HTable<Type>& operator=(const HTable<Type>& that);
HTable(const HTable<Type>& that);
void insert(const Type& v);
bool findAndRemove(const Type& v);
void clear();
int find(const Type& v) const;
private:
SLList<Type>* ht;
unsigned int (*hFunct) (const Type &v);
unsigned int numOfBuck;
};
template<typename Type>
HTable<Type>::HTable(unsigned int numOfBuckets, unsigned int (*hFunction) (const Type &v))
{
ht = new SLList<Type>[numOfBuckets];
this->numOfBuck = numOfBuckets;
this->hFunct = hFunction;
}
template<typename Type>
HTable<Type>::~HTable()
{
delete [] ht;
ht = nullptr;
}
template<typename Type>
HTable<Type>& HTable<Type>::operator=(const HTable<Type>& that)
{
if(this != &that)
{
delete [] this->ht;
this->hFunct = that.hFunct;
this->numOfBuck = that.numOfBuck;
this->ht = new SLList<Type>[numOfBuck];
for(unsigned int i = 0; i < this->numOfBuck; i++)
this->ht[i] = that.ht[i];
}
return *this;
}
template<typename Type>
HTable<Type>::HTable(const HTable<Type>& that)
{
this = *that;
}
template<typename Type>
void HTable<Type>::insert(const Type& v)
{
ht[hFunct(v)].addHead(v);
}
template<typename Type>
bool HTable<Type>::findAndRemove(const Type& v)
{
SLLIter<Type> iter(ht[hFunct(v)]);
for(iter.begin(); !iter.end(); ++iter)
{
if(v == iter.current())
{
ht[hFunct(v)].remove(iter);
return true;
}
}
return false;
}
template<typename Type>
void HTable<Type>::clear()
{
for(unsigned int i = 0; i < this->numOfBuck; ++i)
ht[i].clear();
}
template<typename Type>
int HTable<Type>::find(const Type& v) const
{
SLLIter<Type> iter(ht[hFunct(v)]);
for(iter.begin(); !iter.end(); ++iter)
{
if(v == iter.current())
return hFunct(v);
}
return -1;
}
My Game.h:
#pragma once
#include "stdafx.h"
#include "HTable.h"
#include "BST.h"
#include "DTSTimer.h"
using namespace std;
class Game
{
public:
Game(void);
virtual ~Game(void);
void refresh();
void input();
unsigned int xorHash(const string &s);
private:
string userInput;
DTSTimer timer;
BST<string> answers;
HTable<string> dictionary;
};
My Game.cpp (this is obviously just a skeleton, since I can't get the member init to work)
#include "Game.h"
Game::Game(void) : dictionary(2048, xorHash)
{
}
Game::~Game(void)
{
}
void Game::refresh()
{
}
void Game::input()
{
}
unsigned int Game::xorHash(const string &s)
{
return 0;
}
I've been working on this for a good while, and have been hitting a wall. I would really appreciate some help on how to get this thing up and running. Let me know if there is another snippet that needs to be seen (I've tried to be thorough in that regard).
You have two problems. The first is that you don't pass the member function pointer properly (the error message tells you exactly what do do). The other problem is that a function pointer is not the same as a member function pointer.
A member function pointer needs an instance object object to call the member function on. And this instance is passed as a hidden first argument, something that normal functions don't have.
For this you might instead turn to std::function and std::bind:
class HTable
{
public:
HTable(unsigned int numOfBuckets, std::function<unsigned int(const Type&)> hFunction);
...
private:
std::function<unsigned int(const Type&)> hFunct;
...
};
Then
Game::Game(void) : dictionary(2048, std::bind(&Game::xorHash, this))
{
}