I want to return a Piece from function. Piece is an abstract class parent for all of my pieces.
Piece* Board::getPieceBySign(char sign, Player& _player1, Player& _player2, Player& _emptyPlayer, int row, int col) const
{
switch (sign) {
case Piece::B_KING:
// Example: King(Player& p, const int row, const int col, Board& b);
return new King(_player1, row, col, *this);
case Piece::B_QUEEN:
return new Queen(_player1, row, col, *this);
case Piece::B_ROOK:
return new Rook(_player1, row, col, *this);
case Piece::B_KNIGHT:
return new Knight(_player1, sign, row, col, *this);
case Piece::B_BISHOP:
return new Bishop(_player1, sign, row, col, *this);
case Piece::B_PAWN:
return new Pawn(_player1, sign, row, col, *this);
case Piece::W_KING:
return new King(_player2, sign, row, col, *this);
case Piece::W_QUEEN:
return new Queen(_player2, sign, row, col, *this);
case Piece::W_ROOK:
return new Rook(_player2, sign, row, col, *this);
case Piece::W_KNIGHT:
return new Knight(_player2, sign, row, col, *this);
case Piece::W_BISHOP:
return new Bishop(_player2, sign, row, col, *this);
case Piece::W_PAWN:
return new Pawn(_player2, sign, row, col, *this);
case Piece::EMPTY:
return nullptr;
}
}
In every line, I get an error that says the arguments are not as they should be. And it's not true. Maybe because I try to initialize memory inside of a switch?
no instance of constructor matches the argument list
King.h
#pragma once
#include "Queen.h"
class King :
public Queen
{
public:
King(Player& p, const int row, const int col, Board& b);
bool isWayfree(const int destRow, const int destCol) const override;
bool isLeagalMove(const int destRow, const int destCol) const override;
};
Piece* Board::getPieceBySign(char sign, Player& _player1,
Player& _player2, Player& _emptyPlayer, int row, int col) const
That trailing const indicates that this is a const method. In const methods, the this object is const. That's what it means to be a const method.
King(Player& p, const int row, const int col, Board& b);
*this gets passed in as a last parameter to this constructor, however the parameter is a Board &, and not a const Board &. This is the reason for the compilation error. You either have to make that a const Board &b, or getPieceBySign must be a non-const class method.
Now that you know the reason, you can go back and look at your compiler's full error message, including everything that follows the initial "no instance of constructor matches the argument list"; and you should be able to see that's exactly what your compiler is telling you, in its own way.
Related
I want to create a simple 3x3 matrix class and be able to access its contents by the subscript operator. Here's the code:
// Matrix.h
class Matrix {
private:
int matrix[3][3];
public:
int* operator[](const int index) const;
};
// Matrix.cpp
int* Matrix::operator[](const int index) const {
return this->matrix[index];
}
I want to be able to access the elements of the array no matter whether the Matrix's object is const or non-const. But I get the following error from the compiler:
error: invalid conversion from 'const int*' to 'int*' [-fpermissive]
I did some research and I have a hypothesis: maybe, because I have declared this member function as a const function, inside its definition the compiler treats (it masks) all of the the object's non-mutable members as const members, so that would be the reason the compiler says it's an invalid conversion from 'const int*' to 'int*'. My question: Is this hypothesis correct? And if it's not, why does that happens? I think it makes sense and would be a great way of ensuring the const-ness of the 'const Matrix *this' object.
Compiler Info: gcc 5.3.0 downloaded from equation.com
You are absolutely right about the reason why you get the error: inside a member function marked const the compiler implicitly treats all data members of the class as if they were declared with a const qualifier.
The fix is really straightforward - you can override the same operator twice, providing a const and a non-const versions:
class Matrix {
private:
int matrix[3][3];
public:
const int* operator[](const int index) const;
int* operator[](const int index);
};
// Matrix.cpp
const int* Matrix::operator[](const int index) const {
return this->matrix[index];
}
int* Matrix::operator[](const int index) {
return this->matrix[index];
}
The compiler will figure out which overload to call based on the context. It will call const version if the Matrix itself is const, and the non-const version otherwise.
When you declare a class method (and operator is a class method) const, that means you can only call const methods on your class's fields and return only const pointers or references to class fields. In order to compile, you need to make up your mind to have either:
const int* Matrix::operator[](const int index) const { return this->matrix[index]; }
or
int* Matrix::operator[](const int index) { return this->matrix[index]; }
or both.
int* Matrix::operator[](const int index) const {
return this->matrix[index]; }
Here you say you don't modify the state of your object by specifying function as const.
But you are returning a pointer to your instance variable - and through that pointer it is possible to change value of the instance variable of your class (and thus the state).
So you can create a non const version of that operator to avoid that issue.
You are getting this error because you are return a pointer from a const member function (or operator).
const member function and operator should not change any non-mutable member neither return pointers that can change them later.
Make your operator return const pointer rather than pointer.
class Matrix {
private:
int matrix[3][3];
public:
int const* operator[](const int index) const;
};
// Matrix.cpp
int const* Matrix::operator[](const int index) const {
return this->matrix[index];
}
Live Demo
Change this:
int* Matrix::operator[](const int index) const
to this
const int* Matrix::operator[](const int index) const
You cannot return mutable pointer to data member from const function.
Or you may create two versions of operator: const and non const:
const int* Matrix::operator[](const int index) const;
int* Matrix::operator[](const int index);
PS. And anyway it's a very bad practice to return pointer or reference to internal class members.
hope this helps:
#include<iostream>
using namespace std;
class Matrix
{
private:
int matrix[3][3];
public:
const int* operator[](const int index) const;
Matrix(int* value); // need an initializer though :)
};
const int* Matrix::operator[](const int index) const
{
return this->matrix[index];
}
Matrix::Matrix(int* value)
{
for(int i=0; i<3;i++)
{
for (int j=0; j<3; j++)
{
matrix[i][j]= *value;
value++;
}
}
}
int main( void )
{
int arr[] = {1,2,3,4,5,6,7,8,9};
Matrix C(arr);
const int *c;
c = C[0];
for(int i=0;i<3;i++)
{
cout << *c << ends;
c++;
}
return 0;
}
Is it still undefined behavior to cast away const from a pointer to an object if only const methods are ever be called after the cast?
I'm trying to implement both an iterator and const_iterator for a class where the dereferenced iterator is a proxy object with a small amount of state and a pointer to the parent object (simplified below)
Although the const qualified proxy only calls const methods on the parent it still requires a non-const pointer in the constructor.
class query {
public:
int get (int r, int c) const;
void set (int r, int c, int v);
class iterator {
iterator (query *q, int r) : m_qry(q), m_row(r) {}
row operator* const () { return row(m_qry, m_row); }
query *m_qry;
int m_row;
};
class const_iterator {
const_iterator (const query *q, int r) : m_qry(q), m_row(r) {}
const row operator* const () {
// protected constructor for row needs cast
return row(const_cast<query *>(m_qry), m_row);
}
const query *m_qry;
int m_row;
};
iterator begin() { return iterator(this, 0); }
const_iterator begin() { return const_iterator(this, 0); }
};
class row {
friend query;
public:
int get (int col) const {
// can be called by both row and const row
return m_qry->get(m_row, col);
}
void set (int col, int v) {
// cannot be called for const row
return m_qry->set(m_row, col, v);
}
protected:
row (query *q, int row) : m_qry(q), m_row(r) {}
private:
query *m_qry;
int m_row;
};
I would prefer to avoid using different classes for the differing iterators as this would require considerable code duplication.
If this is not possible are there any other alternative design patterns with good performance?
In a const method, the this pointer is a const type.
So given that it's implicitly cast back to const, the behaviour is well defined.
I have a matrix of bool values
class BoolMatix
{
};
I would like to implement 2 subscript operators that can do this
BoolMatix b(...);
b[5]=true;
and
bool val=GetTruth(5);
GetTruth(5) will return b[5]
I have tried this
const bool operator[](int index);
but this seems to work with GetTruth(index n) only, how about the assignment ?
You have to return a reference
bool& BoolMatrix::operator [](int index);
const bool operator[](int index);
You return a const bool with this, so you just cannot assign something to it
I have a class that represents a diagonal matrix. I only store the elements along the diagonal, so I don't waste space with a bunch of 0's. However, I still want to be able to use double brackets to access elements in the array. To get around that, I use an inner class, like this:
template <class T>
class DiagonalMatrix
{
private:
const T ZERO = 0;
int _size;
Vector<T> _data;
class row
{
private:
DiagonalMatrix<T>* _parent;
int _row;
public:
row(DiagonalMatrix<T>* parent, const int row)
: _parent(parent), _row(row) {}
T& operator[](const int i);
};
class const_row
{
private:
const DiagonalMatrix<T>* const _parent;
int _row;
public:
const_row(const DiagonalMatrix<T>* const parent, const int row)
: _parent(parent), _row(row) {}
const T& operator[](const int i) const;
};
friend class row;
friend class const_row;
public:
row operator[] (const int i);
const const_row operator[] (const int i) const;
// other stuff
};
And here are the relevant definitions:
template<class T>
typename DiagonalMatrix<T>::row DiagonalMatrix<T>::operator[](const int i)
{
if (i < 0 || i >= _size)
{
throw IndexOutOfBoundsException(i);
}
return DiagonalMatrix<T>::row(this, i);
}
template <class T>
T& DiagonalMatrix<T>::row::operator[](const int i)
{
if (i < 0 || i >= _parent->_size)
{
throw IndexOutOfBoundsException(i);
}
if (row == col)
{
return _parent->_data[row];
}
// TODO Add a real exception
throw "Cannot modify non-diagonal elements";
}
With similar definitions for the const versions, except the const operator[] returns a reference to the constant ZERO instead of throwing for non-diagonal elements.
So here is my problem: The non-const version is being called even when I don't need to modify anything. For example, this throws my error string:
DiagonalMatrix<double> diag(5);
// fill in the diagonal elements with some values
cout << diag[0][2] << endl;
However, if I remove the non-const versions of the operator, it behaves as expected and outputs a 0.
I've also tried something like:
T& at(const int row, const int col);
const T& at(const int row, const int col) const;
// in main:
cout << diag.at(0, 2) << endl;
But this has the same issue. So I have two questions:
1) Why does C++ choose the non-const version of the function over the const version even when I am not assigning to the result? Doesn't operator<< typically pass the right-hand object by const&?
2) How can I get around this? I'd rather not have separate get() and set() functions if I can help it.
1) Why does C++ choose the non-const version of the function over the const version even when I am not assigning to the result? Doesn't operator<< typically pass the right-hand object by const&?
It choose the non-const version because diag is not a const object.
2) How can I get around this? I'd rather not have separate get() and set() functions if I can help it.
You can define a const refrence to diag and use it to print values:
const DiagonalMatrix<double> &const_diag = diag;
cout << diag[0][2] << endl; // call const version
Or you define a function to print values and pass a const reference in:
void show_diag(const DiagonalMatrix<double> &diag)
{
cout << diag[0][2] << endl; // call const version
}
show_diag(diag);
Why do it twice?
These 2 lines, why do it like this way? Is one enough?
inline T& operator() (int row, int col) { return this->m_data[row*NC + col]; }
const inline T& operator() (int row, int col) const { return this->m_data[row*NC + col]; }
thank you
*
* 2-DIMENSIONAL ARRAY
*
* Simulated by 1-dimension array.
******************************************************************************/
#ifndef __2D_ARRAY_H__
#define __2D_ARRAY_H__
#include <stdint.h>
#include <stdlib.h>
namespace alg {
/**
* 2D Array definition
*/
template <typename T=char>
class Array2D {
private:
uint32_t NR; // num of rows
uint32_t NC; // num of columns
T * m_data; // the place where the array resides.
public:
/**
* construct an array of size [nrow,col]
*/
Array2D(uint32_t nrow, uint32_t ncol) {
NR = nrow;
NC = ncol;
m_data = new T[nrow*ncol];
}
/**
* destructor
*/
~Array2D() {
delete [] m_data;
}
private:
Array2D(const Array2D&);
Array2D& operator=(const Array2D&);
public:
/**
* return number of rows of this array
*/
inline const uint32_t row() const { return NR; }
/**
* return number of columns of this array
*/
inline const uint32_t col() const { return NC; }
/**
* return the value by the given (row, col);
*/
inline T& operator() (int row, int col) { return this->m_data[row*NC + col]; }
const inline T& operator() (int row, int col) const { return this->m_data[row*NC + col]; }
inline T* operator[] (int row) { return &(m_data[row * NC]); }
inline const T* operator[] (int row) const { return &(m_data[row * NC]); }
/**
* clear the array by a given value
*/
void clear(const T & value) {
for(uint32_t i=0; i<NR*NC;i++){
m_data[i] = value;
}
}
};
}
#endif //
One is const and the other is not.
The difference is that when you have a const reference to a Array2D you're only allowed to call member functions marked const. In this case that means the 2nd version, where it must necessarily return a const reference to the element it holds.
If you have a non-const reference, though, that 2nd version means you can't use operator() to make any changes to your Array2D.
If you look at standard library containers like std::vector you'll see that they do the same thing. You can get an iterator from begin() and a const_iterator from begin() const.
The first, non-constant version returns a reference that can be modified. If you have a constant object, you still want to be able to at least read the value, so you have to provide a second constant version.
The two () operators are not the same. inline T& operator() (int row, int col); returns a reference that allows the returned value to be modified. const inline T& operator() (int row, int col) const returns a reference that disallows the returned value from being modified. Also if the calling object is a const alg::Array2D&, than it can ONLY use the const operator();. So in order to allow users of the Array2D class to properly use const objects. It is best practice to implement both signatures for the operator ().
You could have a function void make_something (const Array2D<char> &input, Array2D<char> &output). This function lets input untouched, makes some operation with it, and writes the result to output. Reading from input would only be possible if there is also a const operator.
inline T& operator() (int row, int col) { return this->m_data[row*NC + col]; }
returns a non-const reference to the data in m_data[row * NC + col], which means I can do
auto& ref = obj(x, y);
ref = BAD_DATA;
and your object can't stop me. The const variant protects against this, and can be fingerprinted as const because it has no side effects on the object as a result.
inline const T& operator() (int row, int col) const { return this->m_data[row*NC + col]; }
This allows me to propagate constness outwards:
void myFunc(const Object& obj) /* I'm only going to look */
{
const auto& ref = obj(x, y);
std::cout << x << ',' << y << " = " << ref << '\n';
}