I have the following classes:
class Point
{
private:
Vector2d _coordinates;
int _label;
public:
Point(const double x = 0.0, const double y = 0.0);
Point(Vector2d coordinates);
void setCoordinates(const double x, const double y) {_coordinates(x, y);}
const Vector2d& getCoordinates() const {return _coordinates;}
int getPointLabel() const{ return _label;}
void setPointLabel(int label);
class PolygonCutter
{
//output parameters
vector<Point> _newPoints;
vector< vector<Point>> _cuttedPolygons;
public:
void AddLabels(const vector<Point> &points, const vector<const unsigned int>&polygonVertices);
};
I working on PolygonCutter. i need it to be just a manager that uses a methodAddLabels to set the member _label of each Point in vector points to the integers passed as the vector polygonVertices
How can I do it? I am having trouble because I am not able to access the method setPointLabel(int label) from here:
My try contains the following errors:
void AddLabels(const vector<Point> &points, const vector<const unsigned int>&polygonVertices);
{
int originalNumberOfVertices = points.size();
for(int i = 0; i<originalNumberOfVertices ; i++)
{ int label = polygonVertices[i]; // ERROR type 'const vector<const unsigned int>' does not provide a subscript operator
const Point& point = points[i];
point.setPointLabel(label); // ERROR 'this' argument to member function 'setPointLabel' has type 'const Point', but function is not marked const
}
}
in AddLabels method, vector points is const. setPointLabel is non-const member function. non-const member functions can only be invoked for non-const objects. Either
remove const from const vector &points , or
mark function setPointLabel const.
Related
Having trouble with overloading operator<. I am trying to overload the operator< so that I can sort my Line2D object based on pt1's x. But I am having trouble figuring out how to declare the function.
I am getting the error:
object has type qualifiers that are not compatible with the member function "Point2D::getX".
What I have tried: removing const, putting Point2D &l2dobj instead.
class Line2D
{
private:
Point2D pt1;
Point2D pt2;
public:
bool operator<( const Line2D &l2dobj)
{
return (pt1.getX() < l2dobj.pt1.getX());
}
}
class Point2D
{
protected:
int x;
int y;
public:
int getX();
int getY();
}
Point2D::getX doesn't accept const instance, you cannot apply it on l2dobj while it is a const reference, change getX (and a priori getY) to :
class Point2D
{
protected:
int x;
int y;
public:
int getX() const;
int getY() const;
};
As a general way declare the methods const the more you can, and same for their parameters
i have a sparse matrix that is created with two arrays and each array index have a linked list the non zero numbers are in there including the i and j indexs
the header
class MNode {
public:
double _data;
int _indexI, _indexJ; // the place of the node in the matrix
// clarification: _nextRow is a pointer to the next columns in the row
MNode* _nextRow, *_nextCol;
MNode(double data, int i, int j);
};
private:
string _type;
MNode** _rowHead, **_colHead;
int _rowSize, _colSize;
int _elemNum;
void setValue(int, int, double);
void removeElement(int, int);
void insertNode(MNode*);
bool IsExist(int, int);
void setElementByType(int i, int j, double data);
public:
// construct a 'rows X cols' matrix.
SMatrix(int rows, int cols,string type);
// set the (i,j) element to be 'data'
void setElement(int i, int j, double data);
// destroy this matrix.
~SMatrix();
double getElement(int, int);
friend std::ostream& operator<<(std::ostream& os, const SMatrix& mat);
SMatrix& operator = (const SMatrix& other);
SMatrix & operator+(const SMatrix & other) const;
};
the cpp here is the overloading + function i get an erorr
cannot convert this pointer to const SMatrix to Smatrix&
SMatrix &SMatrix::operator +(const SMatrix& other) const {
SMatrix temp(3, 3, "any") ;
if (other._rowSize == this->_rowSize&&other._colSize == this->_colSize&&other._type == this->_type) {
for (int j = 0; j < other._colSize; j++) {
for (int i = 0; i < other._rowSize; i++) {
temp.setElement(i, j, (other.getElement(i, j) + this->getElement(i, j)));
}
}
}
return temp;
}
here is the contructor
SMatrix::SMatrix(int rows, int cols,string matType )
{
_type = matType;
_rowSize = rows;
_colSize = cols;
_elemNum = 0;
_rowHead = new MNode*[rows];
if (!_rowHead)
{
cout << "allocation error";
exit(1);
}
_colHead = new MNode*[cols];
if (!_colHead)
{
cout << "allocation error";
exit(1);
}
for (int i = 0; i < rows; i++)
{
_rowHead[i] = NULL;
}
for (int i = 0; i < cols; i++)
{
_colHead[i] = NULL;
}
}
iam not sure what i need to do the signature of the function is given and cant be chanbged any idea?
You've declared other to be a reference to const:
SMatrix & operator+(const SMatrix & other) const;
^^^^^
You call the member function getElement on that reference:
temp.setElement(i, j, (other.getElement(i, j) + this->getElement(i, j)));
^^^^^^^^^^^^^^^^
You've declared getElement to be non-const:
double getElement(int, int);
^
You may only call const member functions on const references.
the signature of the function is given and cant be chanbged any idea?
If the signature of getElement can't be changed, then you've been dealt a badly written signature. There should be no good reason why a getter couldn't be const. That said, since you're within the class, you can access all members directly without using a getter.
There's another bug. You've declared operator+ to return a reference.
SMatrix &SMatrix::operator +(const SMatrix& other) const
^
But you return a local automatic variable temp:
SMatrix temp(3, 3, "any") ;
// ...
return temp;
Automatic variables are destroyed at the end of the function. Therefore the returned reference will always be dangling and any use of it would have undefined behaviour.
the signature of the function is given and cant be chanbged any idea?
If the signature of operator+ can't be changed, then you've been dealt a badly written signature. The function really should return by value. There's no sensible solution that could return a reference. Using a static local would technically work, but that has some limitations on usage that aren't apparent from the interface.
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;
}
I'm trying to implement a operator function to solve the next error :
error: assignment of member 'Animal::weight' in read-only object weight +=amount*(0.02f);
My Animal.cpp function looks like:
void Animal::feed(float amount) const
{
if (type == "sheep"){
amount=amount*(0.02f);
weight+=amount;
}else if (type == "cow"){
weight +=amount*(0.05f);
}else if (type == "pig"){
weight +=amount*(0.1f);
}
return weight;
}
Animal.h (short version):
class Animal
{
public:
Animal(std::string aType, const char *anSex, float aWeight, QDateTime birthday);
float getWeight() const {return weight;};
void setWeight(float value) {weight = value;};
float feed(float amount) const;
void feedAnimal(float amount);
private:
float weight;
};
float operator+=(const float &weight,const float &amount);
Then I implemented a += operator.
float operator+=(const float &weight,const float &amount);
Which is also included then in the .cpp file:
Animal & operator +=(Animal &animal, float amount){
float w = animal.getWeight();
animal.setWeight(w+amount);
}
I worked with a reference so that the weight is update for every animal. So I can call the function feed, and when I want to know the result I do it with the get function:
float getWeight() const {return weight;};
But for some reason I catch the next error :
'float operator+=(const float&, const float&)' must have an argument of class or enumerated type
float operator+=(const float &weight,const float &amount);
Any solutions for this?
For use the feed function I also have a problem. I have my Farm.cpp class where i loop for all the animals in the farm.
void Farm::feedAllAnimals(float amount)
{
for (auto an : animals) {
if(an != nullptr) {
an->feed(amount);
}
}
std::cout << "all animals fed with " << amount << "kg of fodder";
}
And in my .h file I have those functions :
Public:
void feedAllAnimals(float amount);
Private:
std::vector<std::shared_ptr<const Animal>> animals;
My error:
error: passing 'const Animal' as 'this' argument of 'float Animal::feed(float)' discards qualifiers [-fpermissive] an->feed(amount);
^
You declared function feed as a const member function
void feed(float amount) const;
^^^^^
You may not change the object if it is a constant object.
As for operator
float operator+=(const float &weight,const float &amount);
then you may not overload operators for fundamental types.
I think you mean either the following
Animal & operator +=( Animal &animal, float amount);
For example
Animal & operator +=( Animal &animal, float amount)
{
animal.setWeight( animal.getWeight() + amount );
return animal;
}
or an operator declared as a member function within the class like
Animal & operator +=( float amount );
As for the vector then the template parameter must be without qualifier const if you are going to change objects pointed to by the elements of the evctor
std::vector<std::shared_ptr<Animal>> animals;
So I have a vector class that looks a bit like this (most methods stripped out for clarity):
class D3Vector {
private:
double _values[3];
public:
const double& operator[](const int index) const;
double& operator[](const int index);
};
double& D3Vector::operator[](const int index) {
assert(index >= 0 && index < 3);
return _values[index];
}
const double& D3Vector::operator[](const int index) const {
assert(index >= 0 && index < 3);
return _values[index];
}
And at some point in my code I call this array subscript overload as follows:
void func(D3Vector centre, double radius) {
double limits[6];
int i;
for (i = 0; i < 3; i++) {
// both these lines cause the error...
limits[i] = centre[i] - radius;
limits[i + 3] = centre[i] + radius;
}
...
}
but I get this error at compile time:
error: invalid types '<unresolved overloaded function type>[int]' for array subscript
Now, I have fiddled around with the signatures of the overload functions, adding and removing the reference symbols, adding and removing const, but I'm really just guessing here.
What is the sensible way to write the array subscript operator overloads for a vector class for real numbers like this which allow us to do simple things like:
instance[i] = 5.7;
and
new_value = instance[j] + 17.3;
?
EDIT: the full class specification, as requested:
class D3Vector {
private:
double _values[3];
public:
// constructors - no args inits to 0.0
D3Vector();
D3Vector(const double x, const double y, const double z);
// binary + and -:
D3Vector operator+(const D3Vector& right);
D3Vector operator-(const D3Vector& right);
// unary -, reverses sign of components:
D3Vector operator-();
// binary *, scales components.
D3Vector operator*(const double scale);
// the same, as self-assignment operations:
D3Vector& operator+=(const D3Vector& right);
D3Vector& operator-=(const D3Vector& right);
D3Vector& operator*=(const double scale);
// subscript operator, for member data access.
const double& operator[](const int index) const;
double& operator[](const int index);
// dot product:
double dot(D3Vector& right);
// cross product:
D3Vector cross(D3Vector& right);
// shortcut to vector length:
double mod();
// faster way of getting length squared:
double mod_squared();
};
As commenters are pointing out, this error pops up when you try and call a function with brackets [] instead of parentheses (). This is exactly what is happening here, and wasn't obvious because I simplified the code example.
In the question, I post and example function called func - this was in fact a constructor of an inherited class (hence, rather than post all the code, I simplified.)
The base class contains all we need to know:
class D3Shape {
protected:
double l[6];
virtual void initilise_limits() = 0;
public:
virtual bool contains(D3Vector point) = 0;
vector<double> limits();
};
i.e. I had confused l, the private member variable storing the double[6] I was looking for, with limits(), a function for retrieving them in a std::vector<double> container. This was complicated by the fact that I was (successfully) using my real array-subscript-overloaded class on the same line, which confused me! The compiler error "column number" on the file was in fact pointing to the first character after the =, further muddying the waters.
Many thanks to everyone who commented.