Static member function cannot access protected member of class - c++

My understanding is static member functions can access private, protected members of the class.
Here in my code, sortPoint2DXAsc should be able to access X and Y since it's member function of Point2D. But I get this error:
Point2D.h: In function ‘bool sortPoint2DXAsc(const Point2D&, const Point2D&)’:
Point2D.h:22:7: error: ‘int Point2D::x’ is protected
Point2D.cpp:41:21: error: within this context
Point2D.h:22:7: error: ‘int Point2D::x’ is protected
Point2D.cpp:41:31: error: within this context
Point2D.h:22:7: error: ‘int Point2D::x’ is protected
Point2D.cpp:41:44: error: within this context
Point2D.h:22:7: error: ‘int Point2D::x’ is protected
Point2D.cpp:41:55: error: within this context
Point2D.h:23:7: error: ‘int Point2D::y’ is protected
Point2D.cpp:41:67: error: within this context
Point2D.h:23:7: error: ‘int Point2D::y’ is protected
Point2D.cpp:41:77: error: within this context
Here is my code:
class Point2D
{
protected:
int x;
int y;
public:
//Constructor
Point2D();
Point2D (int x, int y);
//Accessors
int getX();
int getY();
//Mutators
void setX (int x);
void setY (int y);
static bool sortPoint2DXAsc (const Point2D& left, const Point2D& right);
};
bool sortPoint2DXAsc (const Point2D& left, const Point2D& right)
{
return (left.x < right.x) || ((left.x == right.x) && (left.y < right.y));
}

I think you want something like this code tested :
class Point2D {
protected:
int x;
int y;
public:
//Constructor
Point2D();
Point2D (int x, int y);
//Accessors
int getX() const {return x; }
int getY() const {return y;}
//Mutators
void setX (int x) {/*Do something with x*/}
void setY (int y) {/*Do something with y*/}
static bool sortPoint2DXAsc(const Point2D& left, const Point2D& right);
};
bool Point2D::sortPoint2DXAsc (const Point2D& left, const Point2D& right)
{
return (left.getX() < right.getX()) || ((left.getX() == right.getX()) && (left.getY() < right.getY()));
}
You can use static since you're not using this in your function. For example, if you was using this->x instead of left.getX(), you would have received an error because your function is static.
Now, here's a second example where you can access x and y without accessors.
Since you're inside your class definition, x and y are accessible from left and right which are instance of Point2D even if they are protected.

Related

Overloading operator< containing class object

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

returning an object by function without using & (c++) [duplicate]

This question already has answers here:
C++ best practice: Returning reference vs. object
(8 answers)
Closed 5 years ago.
Why do you return an object with function by using &?
For example, lets have a look at the following classes and function:
class Point
{
public:
Point(int x, int y);
int getX() const;
int getY() const;
void setX(int x);
void setY(int y);
void print() const;
private:
int x, y;
};
class Circle
{
public:
Circle(int x, int y, int r, int color);
int getColor() const;
void setColor(int color);
bool contains(const Point &p) const;
void print() const;
private:
const Point center;
int radius, color;
};
class Collection
{
public:
Collection(int radius, int width, int height, int color);
~Collection();
Circle& getCircleAt(const Point &p);
void print() const;
private:
int count;
Circle **circles;
};
Circle& Collection::getCircleAt(const Point &p)
{
for (int i = 0; i < count; i++)
if (circles[i]->contains(p))
return *(circles)[i];
}
The function above returnes a circle.
In the function getCirclet, why is the sign & is necessary ? Why can't I omit it?
In your function
Circle& Collection::getCircleAt(const Point &p)
the return type Circle& means that a reference to on object of type Circle will be returned. If you declared your function
Circle Collection::getCircleAt(const Point &p)
with the same body, then a copy of the object would be returned, if a copy constructor is available. This means in the first case, if you modify the returned object, this will modify the object contained in the Collection, while in the second case, only the copy will be modified.
Note that references cannot be NULL, so you have a problem if your particular function is called with a Point that is not inside any Circle. Returning nothing at all, as you do now, is not an option.

Including const in operator overloading argument list gives error (C++)

I am trying out with operator overloading, for which I wrote below code
class OwnClass
{
private:
int x,y;
public:
OwnClass(int x, int y) { SetX(x); SetY(y); }
int GetX() { return x; }
void SetX(int x) { this->x = x;}
int GetY() { return y; }
void SetY(int y) {this->y = y;}
OwnClass& operator + (const OwnClass &o) // Problematic line
{
this->x += o.GetX();
this->y += o.GetY();
return *this;
}
};
When compiled, following error is shown
fun.cpp(65): error C2662: 'OwnClass::GetX' : cannot convert 'this'
pointer from 'const OwnClass' to 'OwnClass &'
Conversion loses qualifiers
fun.cpp(66): error C2662: 'OwnClass::GetY' : cannot convert
'this' pointer from 'const OwnClass' to 'OwnClass &' Conversion loses
qualifiers
When I modify the code as under, it compiles fine.
OwnClass& operator + (OwnClass &o) // removed const
{
this->x += o.GetX();
this->y += o.GetY();
return *this;
}
I could not understand why so ? I mean I am not able to understand the compiler error.
The parameter o is declared as reference to const, which can't be called with GetX and GetY, because they're non-const member function. You can (and should) change them to const member functions to solve the issue.
int GetX() const { return x; }
int GetY() const { return y; }
BTW: In general binary operator+ is not supposed to return a reference to non-const. It's better to return a new object by value.
OwnClass operator + (const OwnClass &o) const
{
OwnClass r(GetX(), GetY());
r.x += o.GetX();
r.y += o.GetY();
return r;
}
Note for this case operator+ could (and should) be declared as const member function too. And as #M.M suggested, making it non-member function would be better.
The problem is that you are calling non-const member functions on const objects. Make getters const to fix this problem:
int GetX() const { return x; }
int GetY() const { return y; }

Access member variables/getters from comparison function

I'm basically trying to write comparator function to sort by x then y value of Object P1 and Pt2 in both ascending and descending order.
Now I'm having an error that x and y is protected but how do I use getters correctly in sort, please?
I'm still pretty confused. I tried to use this but doesn't work.
bool Line2D::sortLine2DPtAsc (const Point2D& left, const Point2D& right)
{
return (left.pt1.getX() < right.pt1.getX()) || ((left.pt1.getX() == right.pt1.getX()) && (left.pt1.getY() < right.pt1.getY()));
}
Error using getters:
Line2D.cpp:25:15: error: ‘const class Point2D’ has no member named ‘pt1’
Line2D.cpp:25:34: error: ‘const class Point2D’ has no member named ‘pt1’
Line2D.cpp:25:56: error: ‘const class Point2D’ has no member named ‘pt1’
Line2D.cpp:25:76: error: ‘const class Point2D’ has no member named ‘pt1’
Line2D.cpp:25:97: error: ‘const class Point2D’ has no member named ‘pt1’
Line2D.cpp:25:116: error: ‘const class Point2D’ has no member named ‘pt1’
here's my code:
class Line2D
{
private:
Point2D pt1;
Point2D pt2;
public:
//Constructor
Line2D ();
Line2D (Point2D pt1, Point2D pt2);
//Accessors
Point2D getPt1();
Point2D getPt2();
double getScalarValue(); //returns the value of attribute length
//Mutators
void setPt1 (Point2D pt1);
void setPt2 (Point2D pt2);
static bool sortLine2DPtAsc (const Point2D& left, const Point2D& right) ;
}
bool Line2D::sortLine2DPtAsc (const Point2D& left, const Point2D& right)
{
return (left.x < right.x) || ((left.x == right.x) && (left.y < right.y));
}
Use the version with the getters, but replace left.pt1.getX() with left.getX(), etc.
And I'm guessing that in your Point2D class, you need to change
double getX();
to
double getX() const;
And likewise for getY.
Being passed const Point2D& left, const Point2D& right, you are under contract not to modify any values in those objects. You can only call their members functions that are declared const (they will not change the object).
bool Line2D::sortLine2DPtAsc (const Point2D& left, const Point2D& right)
your parameters are of type Point2D, maybe you meant to have them of type Line2D
if the function is sorting lines, why are you passing it points ;)
pt1 and pt2 are members of the Line2D class not the your Point2D class

Overloading subscription operator() or [] with no code repetition

I have two versions of operator():
const A& operator(int x ,int y) const;
A& operator(int x ,int y);
But I don't know what would be the best way to avoid code repetition (because they essentially have the same logic).
I did read the awesome FAQ regarding operator overloading (and some other questions) but did not find answer.
EDIT_1: I've tried the suggestion that Skizz proposed but something like that does not quite work for me but maybe I've missed something:
Because this works while this does not compile giving the following error:
error: invalid initialization of reference of type ‘int&’ from expression of type ‘const value_type {aka const int}’
If both methods 'essentially have the same logic' then surely they should both be marked const. If they do behave differently, should they be called the same thing?
What you need is a third, hidden method that does the common thing, like this:-
const A& operator(int x ,int y) const
{
return Common (x,y);
}
A& operator(int x ,int y)
{
return Common (x,y);
}
A& Common (int x, int y) const
{
// common code
}
This takes advantage of the implicit non-const to const conversion. In the first method, the this object remains const in the call to Common but the non-const return value is converted to const. In the second, the non-const this object is converted to a const this object and the return object is unchanged.
If you have the data in question as shared/unique pointer, you are able to forward it to a common function:
class X {
public:
const A& operator () (int x ,int y) const {
common(data, x, y);
return *data;
}
A& operator () (int x ,int y) {
common(data, x, y);
return *data;
}
private:
void common(std::shared_ptr<T>, int x ,int y) const;
std::shared_ptr<A> data;
};
Now you are able to access the T* via data.get() which is 'T* get() const'.
(Note: I consider the common function a bad design)
You might do, also:
class X {
public:
const A& operator () (int x ,int y) const {
common(x, y);
return data;
}
A& operator () (int x ,int y) {
// ... make mutations
common(x, y);
// ... make mutations
return data;
}
void common(std::shared_ptr<T>, int x ,int y) const;
T data;
};
Or actually, making the data mutable, if it is not breaking logical const:
class X {
const A& operator () (int x ,int y) const {
// ... make mutations on the mutable data, only
return *lazy_evaluated_data;
}
A& operator () (int x ,int y) {
const X& self = *this;
self(x, y);
return *lazy_evaluated_data;;
}
private:
mutable T lazy_evaluated_data; // or a cache
};
Write a helper function and call it from both operators. You'll need to do some const_cast<...>(this) which can be ugly, but it's a common pattern.