"Call to implicitly deleted default constructor of "error - c++

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.

Related

Why can't this derived object access the base class' post-decrement method?

class Player
{
private:
int score;
public:
Player(int number);
~Player();
int get_score() { return score; }
Player& operator--();
};
Player::Player(int number)
{
score = number;
}
Player::~Player()
{
}
//-----
//Please turn your attention to this function
//-----
Player& Player::operator--() {
score--;
return *this;
}
Hello all, in the above class, I have overloaded the post-decrement operator to decrease the 'score'. There are two sub classes derived from this class - Computer and Human. From my understanding, they should also have access to this function. However, when I try:
Computer comp_; Human player_;
comp--;
human--;
I get an error saying: 'neither of these classes define this operator or a conversion to a type accessible to the predefined operator'. I am not allowed to redefine this function within the sub classes.
It would really help if someone could help me figure out how to get this code working! <3
You're trying to use the post-decrement operator, but you've declared the pre-decrement operator!
To make this code work, either use pre-decrement comp--; => --comp;. Or switch to defining the post-decrement operator Player& operator--(); => Player& operator--(int);. See a working example here: ideone.
For more on what each decrement/increment operator looks like, see the cppreference page.
The post decrement operator should look like this:
T T::operator--(int); // Inside class definition
T operator++(T& a, int); // Outside class definition
and it's supposed to return a copy of the object like it looked before you decreased its value.
class Player
{
private:
int score;
public:
Player(int number);
virtual ~Player();
int get_score() { return score; }
template<typename T>
friend T& operator--(T& p) { // pre
--p.score;
return p;
}
};
Player::Player(int number) : score(number) {}
Player::~Player() {}
template<typename T>
T operator--(T& p, int) { // post
T save(p);
--p; // using pre
return save;
}
The problem comes from the fact that you only define pre-increment operator.
see https://en.cppreference.com/w/cpp/language/operator_incdec
The pre-increment returns a reference, however the post increment returns a value therefore if you need to retain the type of the object returned. I would define the post-increment as a template and use the implementation of the pre-increment.
namespace Game
{
class Player
{
private:
int score;
public:
Player(int number);
~Player();
int get_score() { return score; }
Player& operator--();
};
Player::Player(int number)
{
score = number;
}
Player::~Player()
{
}
Player& Player::operator--() {
score--;
return *this;
}
template <class T> T operator--(const T& a, int)
{
T save(a);
save--;
return save;
}
class Human : public Player
{
public:
Human(int player) :Player(player) {}
};
class Computer : public Player
{
public:
Computer(int player) :Player(player) {}
};
}
example
int main()
{
Game::Human h(2);
Game::Human h2 = h--;
}

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

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.

Constructor in base and derived class

Program works but I am not sure what is wrong with constructor since every time program runs it gets this error "warning: base class 'Alat' is uninitialized when used here to access 'Alat::ime' [-Wuninitialized]". I suppose it's something wrong how I called a constructor from base class but I am not sure what is problem. Really need help, tnx in advance.
#include <iostream>
#include <string>
using namespace std;
class Alat{
protected:
string ime;
int serBr;
int cena;
public:
void setIme(string i);
string getIme();
void setSerBr(int sb);
int getSerBr();
void setCena(int c);
int getCena();
Alat();
Alat(string i, int sb, int c)
:ime(i),
serBr(sb),
cena(c)
{}
void info();
~Alat();
};
#include "Alat.h"
class Rucni : public Alat{
protected:
int minGodKor;
public:
Rucni():Alat(ime, serBr, cena) //I think here is problem, is it wrong called?
{}
int getminGodKor();
void setminGodKor(int min);
void info();
~Rucni();
};
Let the child default constructor call the default parent constructor, and create another child constructor with parameters to call the corresponding one of the parent:
#include <string>
using std::string;
class Alat
{
protected:
string ime;
int serBr;
int cena;
public:
void setIme(string i)
{
ime = i;
}
string getIme()
{
return ime;
}
void setSerBr(int sb)
{
serBr = sb;
}
int getSerBr()
{
return serBr;
}
void setCena(int c)
{
cena = c;
}
int getCena()
{
return cena;
}
Alat()
{
}
Alat(string i, int sb, int c) : ime(i), serBr(sb), cena(c)
{
}
~Alat()
{
}
};
class Rucni : public Alat
{
protected:
int minGodKor;
public:
Rucni() // implicit call of the parent default constructor
{
}
Rucni(string i, int sb, int c) : Alat(i, sb, c) // explicit call of the corresponding parent constructor
{
}
int getminGodKor()
{
return minGodKor;
}
void setminGodKor(int min)
{
minGodKor = min;
}
~Rucni()
{
}
};
int main()
{
Rucni r;
return 0;
}

How to intitialize const data using constructor

Hi, I've created a class which has three constructors, two integer members & one const int member. So for one constructor I'm using initializer list to assign const int member but I am getting error in other two constructors
Here is my code:
class base
{
public:
base();
base(const int _count);
base(int a ,int b);
~base();
protected:
int m_ia , m_ib;
const int count;
};
base::base()
{
}
base::base(const int _count):count(_count)
{
}
base::base(int a , int b)
{
m_ia = a ;
m_ib = b;
}
base::~base()
{
}
void main()
{
base *obj2 = new base(1000);
getchar();
}
Number of Errors:2
1.'base::count' : must be initialized in constructor base/member initializer list at base()
2.'base::count' : must be initialized in constructor base/member initializer list at base(int a ,int b)
You should probably make sure all your constructors are initializing all member variables, not just the one's being passed in as arguments. I'd rewrite your constructors as
base::base()
: m_ia() // value initializes i.e. sets to 0
, m_ib()
, count()
{
}
base::base(const int _count)
: m_ia()
, m_ib()
,count(_count)
{
}
base::base(int a , int b)
: m_ia(a)
, m_ib(b)
, count()
{
}
And if you have a C++11 compiler that supports delegating constructors, you could create a 4 constructor that takes 3 arguments and have the other constructors delegate to that one.
base::base()
: base(0, 0, 0)
{
}
base::base(const int _count)
: base(0, 0, _count)
{
}
base::base(int a , int b)
: base(a, b, 0)
{
}
base::base(int a , int b, int count)
: m_ia(a)
, m_ib(b)
, count(count)
{
}
The last constructor can be made private if you don't want it to be part of the class interface.
In c++11 you can have
protected:
int m_ia , m_ib;
const int count = 0;
It works in VS 2013.
As per standard C++ and you current code you have to Initialize your const variable in constructor using initialize list so code can be modified as below :
#include"iostream"
using namespace std;
class base
{
public:
base();
base(const int _count);
base(int a ,int b, const int _count);
~base();
protected:
int m_ia , m_ib;
const int count;
};
base::base():count(0)
{
}
base::base(const int _count):count(_count)
{
}
base::base(int a , int b, const int _count):count(0)
{
m_ia = a;
m_ib = b;
}
base::~base()
{
}
int main()
{
base *obj2 = new base(1000);
getchar();
return 0;
}

Making a structure in class

I am making my first steps in learning OOP . And here is the first problem which I can't solve.
The max function in this class should return the maximum of two numbers . I want to keep the numbers in the private scope and the functions in the public scope . But when I want to use variables from struct data{} in the public scope the compiler says that the variables are not declared . Please tell me why I get these errors .
class myclass{
private:
struct data{
int q ;
int w;
};
public:
void get(int a, int b){
struct data = {a , b}; // here I want to pass the variables to data struct
}
int max (){ // this function returns the biggest number
if(q>w)
return q;
else
return w;
}
};
struct data{
int q ;
int w;
};
only declares a type, not an object, so there are no q and w members anywhere inside your class instances. You need the declare an instance of the struct:
struct {
int q;
int w;
} data;
Then, you can write max as:
int max()
{
if (data.q > data.w)
return data.q;
else
return data.w;
}
(I've no idea what your get method is supposed to do, so I have no replacement for that.)
In C++ "class" and "struct" are close to being synonymous (the same thing). The ONLY difference is that a "struct" defaults to being "public" accessibility while a "class" defaults to private.
Once you understand this, it should become obvious that what you are doing is defining a sub-type within your class.
class myclass {
private: // <- not required, you already said that by saying "class".
struct data {
// <-- this is a class definition with "public:" just here.
...
};
};
C++ allows you to nest class/structure definitions so that you can, for example, create structures that marshal parameters or return values.
class Database {
class Result { ... };
};
...
class Exam {
class Result { ... };
};
These two result classes avoid namespace collision, by being Database::Result and Exam::Result instead of just "Result".
However - these are only definitions. They do not - as shown - have any effect on the outlying class, that is: they aren't being used to add a member to the class.
Your code:
class myclass{
private:
struct data{ // <-- this is a TYPE declaration, struct myclass::data
int q ; //
int w; //
}; // <-- no member name here so does not affect myclass itself.
public:
void get(int a, int b){
struct data = {a , b}; // here I want to pass the variables to data struct
}
int max (){ // this function returns the biggest number
if(q>w)
return q;
else
return w;
}
};
Declares a type "myclass::data" but does not add a member of type "myclass::data" to the class. The line "struct data = " is illegal, you're trying to assign values to a TYPE.
It should probably be written as
class MyClass {
int m_q;
int m_w;
public:
void set(int q, int w) {
m_q = q;
m_w = w;
}
int max() const {
return (m_q > m_w) ? m_q : m_w;
// or #include <algorithm> and return std::max(m_q, m_w);
}
};
You only need to hoist q & w into a struct if you are going to reuse that structural definition outside the confines of the class, e.g. in derived or parallel classes where you may want to add more of the same type of thing, in which case, you could perhaps do the following, but if you do it this exact way you'll eventually kick yourself for breaking encapsulation:
class MyClass {
public:
struct Data {
int m_q;
int m_w;
};
private:
Data m_data;
void set(int q, int w) {
m_data.m_q = q;
m_data.m_w = w;
}
int max() const {
return (m_data.m_q > m_data.m_w) ? m_data.m_q : m_data.m_w;
}
};
A better way, if this coupling of members needs to be externally visible to some degree would be:
class MyClass {
public:
class Data {
int m_q;
int m_w;
public:
Data() : m_q(0), m_w(0) {}
Data(int q, int w) : m_q(0), m_w(0) {}
void set(int q, int w) {
m_q = w;
m_w = w;
}
int q() const { return m_q; }
int w() const { return m_w; }
int max() const { return (m_q > m_w) ? m_q : m_w;
};
private:
Data m_data;
public:
MyClass() : m_data() {} // or = default
MyClass(int q, int w) : m_data(q, w) {}
MyClass(const Data& data) : m_data(data) {}
// Read-only access
const Data& data() const { return m_data; }
// To allow write access, e.g. for set:
Data& data() { return m_data; }
};
It's kinda overkill for such a simple case, but welcome to C++: the boilerplate language.
You have defined the structure but there is no object of that type. You should declare an object and you will not get any error.
class myclass{
private:
struct data{
int q ;
int w;
}var;
public:
void get(int a, int b){
var .q= a;
var.w=b; // here I want to pass the variables to data struct
}
int max (){ // this function returns the biggest number
if(var.q>var.w)
return var.q;
else
return var.w;
}
};