0

To demonstrate my problem let's look at the following sample:

#include "stdafx.h"
#include <iostream>

using namespace std;

class MyClass {
public:
    long double x, y;
    MyClass(const long double &xx = 0, const long double &yy = 0);
    long double distance(const MyClass &b) {
        return sqrt((x - b.x)*(x - b.x) + (y - b.y)*(y - b.y));
    }
};

MyClass::MyClass(const long double &xx, const long double &yy) {
    x = xx; y = yy;
}

void WriteDistance(const MyClass &a, const MyClass &b) {
    cout << a.distance(b) << endl;
}

int main()
{
    MyClass a = MyClass(2., 3.);
    MyClass b = MyClass(3., 4.);
    cout << a.distance(b) << endl;
    return 0;
}

There is a class MyClass and there is a class function distance which takes one MyClass variable and returns the distance between an existing point and the argument point.

The problem is: in the main(), the function works (gives no error). However there are errors in the WriteDistance() function, that reads: the object has type qualifiers that are not compatible with the member function "MyClass::distance" and 'long double MyClass::distance(const MyClass &)': cannot convert 'this' pointer from 'const MyClass' to 'MyClass &'.

If I overload the distance function (to take not only one MyClass object, but perhaps also two long doubles, just for the comfort of availability), the error reads: no instance of overloaded function "MyClass::distance" matches the argument list and object (the object has type qualifiers that prevent a match) and 'MyClass::distance': 2 overloads have no legal conversion for 'this' pointer.

The question is: why this error occurs and how to prevent it? I found out that not making the MyClass &a const (so deleting "const") gets rid of the error. But why? Members of this site told me countless times to always pass by const reference to prevent copying of objects. If I cannot pass by const reference, does that mean that my function WriteDistance changes the a object in some way in the process? Is there some workaround to being able to having it really const?

3 Answers 3

4

Your distance function claims to modify the object it is called on, which is why you can't use it on values of type const MyClass.

You should declare it as

long double distance(const MyClass &b) const {
//                                     ^^^^^

This second const means it won't modify class members (i.e. *this is const within the function).

Sign up to request clarification or add additional context in comments.

1 Comment

This is the answer I was looking for. I realized what the probilem is with what I wanted. Thank you!
3

Declare the member function with the qualifier const

long double distance(const MyClass &b) const {
//...

If you want to declare the function with two parameters then make it static. For example

static long double distance(const MyClass &a, const MyClass &b) {
//...

1 Comment

This is interesting: "If you want to declare the function with two parameters then make it static." could you explain why?
-1

You need add a const qualification version function for the const object' usage. We usually provide two version function declaration, const and non-const. The const version is used for const Class object, like your const MyClass &b

void WriteDistance(const MyClass &a, const MyClass &b) const {
    cout << a.distance(b) << endl;
}

1 Comment

not my downvote, but providing a const and a non-const version of a method that actually is const is rather pointless, because you can call a const method on a non-const object (just not the other way around). Moreover passing two parameters instead of making it a member function is an option, but for free functions the ) const { is wrong

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.