Travis Gockel
Travis Gockel

Reputation: 27623

C++: Override method which has the same name as the class

Let's say I have a nice looking base class called base:

class base
{
public:
    virtual void foo() const = 0;
};

Now, I have a class named foo that I would like to inherit from base and override base::foo:

class foo : public base
{
public:
    virtual void foo() const override;
};

This is illegal in C++, as you are not allowed to name a method the same thing as the class (C++ greedily believes methods with the same name as the class are constructors, which are not allowed to have return types). Is there any way around this that doesn't involve changing the name of the class or method? I want external users to be able to create foo classes without the knowledge that there is a method base::foo called by someone else (imagine foo can be both a noun and a verb).

Upvotes: 0

Views: 1059

Answers (4)

Travis Gockel
Travis Gockel

Reputation: 27623

Okay, here's my (slightly evil) solution...

// Create an intermediate class which actually implements the foo method:
class foo_intermediate : public base
{
public:
    virtual void foo() const override;
};

// Derive from that class and forward the constructor along
class foo : public foo_intermediate
{
public:
    using foo_intermediate::foo_intermediate;

private:
    friend class foo_intermediate;

    // Actual implementation for the foo function goes here
    void foo_impl() const;
};

// In some CPP file:
void foo_intermediate::foo() const
{
    // Need to access the typename foo via namespace (global here)
    static_cast<const ::foo*>(this)->foo_impl();
}

Actually calling foo is a bit funny, since this can't work:

void bar()
{
    foo x;
    x.foo(); // <- illegal attempt to access to the foo constructor
}

You must access through an alias:

void baz()
{
    foo x;
    base& rx = x;
    rx.foo(); // legal
}

As an alternative, you can use a typedef:

class foo_impl : public base
{
public:
    virtual void foo() const override;
};

using foo = foo_impl;

This gets around the issue of calling x.foo(), since it no longer appears as a constructor access.


I made a Gist so others could play with the two solutions if they are so inclined.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206567

Is there any way around this that doesn't involve changing the name of the class or method?

No, there isn't.

All methods named foo are special in class foo -- they are constructors. Hence, they cannot be overridden virtual member functions.

Upvotes: 7

rubenvb
rubenvb

Reputation: 76519

I'll take a wild guess and just say NO.

You can have a lot of ambiguities in C++ (that sometimes have to be explicitly disambiguated), but I don't even see a way how a compiler or programmer could disambiguate this situation. Well, A programmer can (a function with a return type is obviously not a constructor), but C++ can't.

Upvotes: 4

Lilymonade
Lilymonade

Reputation: 475

In C++, the only method that can have the class' name is its constructor. So, no. You can't.

Upvotes: 1

Related Questions