|
Let's say I have this code:
interface class IFoo
{
public:
void foo();
};
ref class FooBase : public IFoo
{
public:
virtual void foo() sealed = IFoo::foo
{
}
};
I need to define a new explicit foo() in a derived class, that overrides the sealed method in the base class. How do I do that? I tried a lot of things and none compiled.
ref class FooDerived : public FooBase
{
public:
virtual void foo()
{
}
};
results in
error C4485: 'FooDerived::foo' : matches base ref class method 'FooBase::foo', but is not marked 'new' or 'override'; 'new' (and 'virtual') is assumed
1> .\Dlg.cpp(22) : see declaration of 'FooBase::foo'
1> Specify 'override' (and 'virtual') to override the ref class virtual method
1> Specify 'new' (and 'virtual') to hide the ref class virtual method with a new virtual method
1> Position for 'new' and 'override' keywords is after method parameter list
but if I add new
ref class FooDerived : public FooBase
{
public:
virtual void foo() new
{
}
};
I get
Dlg.cpp(30) : error C2059: syntax error : 'string'
Dlg.cpp(31) : error C2091: function returns function
also
ref class FooDerived : public FooBase
{
public:
virtual void foo() new = FooBase::foo
{
}
};
results in
1>.\Dlg.cpp(30) : error C2059: syntax error : 'string'
1>.\Dlg.cpp(30) : error C2091: function returns function
1>.\Dlg.cpp(31) : warning C4569: 'FooBase::foo' : no members match the signature of the explicit override
1>.\Dlg.cpp(31) : error C3671: 'FooDerived::foo' : function does not override 'FooBase::foo'
and
ref class FooDerived : public FooBase, public IFoo
{
public:
virtual void foo() new = IFoo::foo
{
}
};
generates
1>.\Dlg.cpp(30) : error C2059: syntax error : 'string'
1>.\Dlg.cpp(30) : error C2091: function returns function
1>.\Dlg.cpp(31) : warning C4569: 'IFoo::foo' : no members match the signature of the explicit override
1>.\Dlg.cpp(31) : error C3671: 'FooDerived::foo' : function does not override 'IFoo::foo'
What I'm trying to do is overriding HwndSource.System.Windows.Interop.IKeyboardInputSink.TabInto[^]
Any help is appreciated.
|
|
|
|
|
You could use Renamed Overriding which will work if you're always called through an interface handle.
interface class IFoo
{
public:
void foo();
};
ref class FooBase : public IFoo
{
public:
virtual void foo() sealed = IFoo::foo
{
Console::WriteLine("FooBase");
}
};
ref class FooDerived : public FooBase
{
public:
virtual void derivedFoo() = IFoo::foo
{
Console::WriteLine("FooDerived");
}
};
int main(array<System::String ^> ^args)
{
FooBase^ fb = gcnew FooBase();
fb->foo();
FooDerived^ fd = gcnew FooDerived();
fd->foo();
IFoo^ iface = dynamic_cast<IFoo^>(fb);
iface->foo();
iface = dynamic_cast<IFoo^>(fd);
iface->foo();
return 0;
}
|
|
|
|
|
Perhaps better. This seems to be what you're after to me.
ref class FooDerived : public FooBase
{
public:
virtual void foo() new = IFoo::foo
{
Console::WriteLine("FooDerived");
}
};
John
|
|
|
|
|
Yes. This seem to be what I was looking for. It's curious that out of all my attempts, this one I missed.
BTW, there is a little error in your sample.
FooDerived^ fd = gcnew FooDerived();
fd->foo();
This obviously prints FooDerived.
And the first example, where you say virtual void foo() = IFoo::foo does not compile.
But thanks again for the help.
|
|
|
|
|
Actually, that's not a error in the output, that's a direct paste from running the code and the output.
There is also no compile error for me (this was directly from running code). Notice the function name in FooDerived; it's "derivedFoo()" not "foo()".
FooDerived can only print "FooDerived" when fd->derivedFoo() is called OR when called via an IFoo^. So, calling fd->foo() does call the base class implementation.
virtual void derivedFoo() = IFoo::foo
|
|
|
|
|
It doesn't work in MFC apps with /clr support.
1>.\mfc_mm_2008.cpp(38) : error C2059: syntax error : 'string'
1>.\mfc_mm_2008.cpp(38) : error C2091: function returns function
1>.\mfc_mm_2008.cpp(39) : warning C4569: 'IFoo::foo' : no members match the signature of the explicit override
1>.\mfc_mm_2008.cpp(39) : error C3671: 'FooDerived::foo' : function does not override 'IFoo::foo'
The reason is MFC is rewriting the new operator with
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
So anyone wanting to do this in MFC, make sure you don't have that replacement of new before your declaration of the new function definition.
|
|
|
|
|
Good tip about the DEBUG_NEW screwing up the new keyword.
I tried the code in my MFC + /clr application but we've had to remove those DEBUG_NEW defines for other reasons so I didn't run into this issue. Good to know!
John
|
|
|
|
|
BTW, my kids have spent many hours playing your 'Alchemy' game so thanks for that
|
|
|
|