Reputation: 27623
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
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
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
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
Reputation: 475
In C++, the only method that can have the class' name is its constructor. So, no. You can't.
Upvotes: 1