Esther Esther - 2 months ago 26
C++ Question

How to provide const version of operator -> for a handle class

I am trying to overload my operator-> for a handle class to return const and non const pointer, pointing towards a base class.

Looking at the code i posted, in the trial function, if i add in the const keyword, the error message will be

||=== Build: Debug in Const trial (compiler: GNU GCC Compiler) ===|
C:\Const trial\main.cpp
||In function 'bool trial(Cards_pointer)':|
C:\Const trial\main.cpp|50|error: passing 'const Cards_pointer' as 'this' argument of 'Cards*& Cards_pointer::operator->()' discards qualifiers [-fpermissive]|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|


My question is whether it is possible to do so, if yes, may i know what is the correct implementation?

#include <iostream>
#include<vector>
#include<stdexcept>
#include<algorithm>
using namespace std;

class Cards
{
private:
int x;
public:
Cards():x(3) {}
int rx()const
{
return x;
}
};

class Cards_pointer
{
private:
Cards* cp;
size_t* refptr;

public:
//default constructor
Cards_pointer():cp(0),refptr(new size_t(1)) {}
Cards_pointer(Cards*t):cp(t),refptr(new size_t(1)) {}
//copy constructor
Cards_pointer (const Cards_pointer&s):cp(s.cp),refptr(s.refptr)
{
refptr=s.refptr;
cp=s.cp;
//++*refptr;
*refptr=*refptr+1;
}

Cards*&operator->()
{
if(cp)
return cp;

else throw std::runtime_error("uninitialized Cards");
}

};

bool trial(const Cards_pointer x)
{
if(x->rx()==3)
return true;

return false;
}

int main()
{
Cards_pointer x=new Cards();

bool cond=trial(x);

}

Answer Source

Just return a pointer to const and provide a const qualified overload

class Something {
public:
    void bar() {}
    void foo() const {}
};

class Wrapper {
public:
    Something* operator->() {
        return &this->something;
    }
    const Something* operator->() const {
        return &this->something;
    }
private:
    Something something;
};

int main() {
    const auto c_wrapper = Wrapper{};
    c_wrapper->foo();
    // The below is an error
    // c_wrapper->bar();
    auto m_wrapper = Wrapper{};
    m_wrapper->bar();
}

If you are worried about duplicated code in the const and non const overloads see Const function calling non const or vice versa (to avoid duplication)?