1

Is it possible to overload an operator for only one function. I want to override the '->' operator, but only when it is called with the print function ( ->print() ). I understand this is a weird request, but I am working on fulfilling a certain API, and I would need something like this.

For example:

Cat cat;
cat.walk();
cat->print(); //I want to overload only this call

However, I don't want to overload the '->' operator for all cases. For example:

Cat* cat;
cat->walk(); //this should work normally
cat->print(); //this wouldn't call the print() function, 
              //since I overloaded cat->print()
2
  • Cat* cat; cat->print(); What exactly would this be supposed to do then? Shouldn't compile or what? Commented Mar 11, 2013 at 19:23
  • 1
    Note that when the left side of -> is a pointer, the arrow operator always has its built-in meaning, and no operator-> will change what the expression means. Commented Mar 11, 2013 at 19:26

3 Answers 3

4

You can overload the -> operator with a dummy return object. The true print() method can be made private and only accessible through the accessor. In a minimal example:

#include <iostream>

struct Cat;

struct CatAccessor {
private:
    friend class Cat;
    CatAccessor(Cat& cat) : cat(cat) {}
    Cat& cat;
public:
    void print();
    CatAccessor* operator->() { return this; }
};

struct Cat {
    CatAccessor* operator->() { return CatAccessor(*this); }
    void walk() { std::cerr << "Walk called" << std::endl; }
private:
    void print() { std::cerr << "Print called" << std::endl; }
    friend class CatAccessor;
};

void CatAccessor::print() { cat.print(); }

int main() {
    Cat cat;
    cat.walk();
    cat->print();
    Cat* catp = &cat;
    catp->walk();
    // error: catp->print();
    return 0;
}
Sign up to request clarification or add additional context in comments.

3 Comments

How about if you call any other method of Cat?
@IvayloStrandjev: Just as usual through the Cat class. Updated the example.
This is a bit inefficient as each Cat instance now contains a CatAccessor. I think it could be improved by returning a CatAccessor instance from operator-> and add another operator-> to CatAccessor using the chaining property of operator->.
3

If you can move print() to a base class, it's quite easy:

class CatBase
{
public:
    void print();
};

class Cat : private CatBase
{
public:
    void walk();

    CatBase* operator->() { return this; }
    const CatBase* operator->() const { return this; }
};

2 Comments

@DanielFrey: Nice approach. If you made CatBase a private base, you could fulfill the requirement of print() not being callable directly.
@thiton: Indeed, nice idea! Editing. Thanks!
2

C++ does not allow you to do such thing "directly". Best shot you have is to inherit from the class Cat, make the method print virtual and implement it differently in the child class.

3 Comments

downvoter could you please point out what is incorrect in my answer?
C++ does allow you to do it, as DanielFrey and I have shown. Therefore I think that the answer is a false lead.
@thiton please provide a complete and compilable code that will do what you suggest

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.