Here is my example code:
class Interface {
public:
virtual void foo(const Interface &interface) = 0;
};
class A : public Interface {
public:
void foo(const A &a) {
// do something with another object of same type
}
};
class B : public Interface {
public:
void foo(const B &b) {
}
};
There is a warning:
warning: 'A::foo' hides overloaded virtual function
[-Woverloaded-virtual]
void foo(const A &a) {
^
note: hidden overloaded virtual function 'Interface::foo'
declared here: type mismatch at 1st parameter ('const Interface &' vs
'const A &')
virtual void foo(const Interface &interface) = 0;
How to deal with the problem? Is adding using Interface::foo; in derived class the best solution? I think it's a common problem. Thanks a lot!
void foo(const A &a) does not override void foo(const Interface &interface). While the language allows covariant return types, you can't have covariant parameters as far as I know.
So your void foo(const A &a) is hiding (or at most overloading) the base version of the function.
If you use C++11's override keyword, the compiler should more clearly tell you that you aren't overriding. Or if you try to instantiate an A then it should fail with an error about A being abstract because it hasn't actually overridden foo.
The solution of course is to make the derived versions use the exact same parameter types for foo.
The virtual part of your virtual void foo() function indicates that it can be overridden in a class that inherits Interface. In class A and B, you have used the same function but changed the parameters, which means that the function will be overloaded.
If you want to just override the function in the sub classes, use void foo(const Interface &interface).
For more details on overloading virtual functions see this post: Overloading a virtual function in a child class
Thanks #GargAnkit in comment,Here is my total solotion:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
class Interface {
public:
int compare(const Interface &that) const {
if (this->to_string() < that.to_string()) {
return -1;
} else if (this->to_string() == that.to_string()) {
return 0;
} else {
return 1;
}
}
virtual std::string to_string() const = 0;
};
class A : public Interface {
public:
std::string to_string() const override {
return "A";
}
};
class B : public Interface {
public:
std::string to_string() const override {
return "B";
}
};
int main() {
A a;
B b;
cout << a.compare(b) << endl;
cout << "ok" << endl;
return 0;
}
For a function to be picked as an override of a function in the base class, both function must match exactly - same name, same parameters, same const/volatile qualification. If the function only differ by the qualification, they will be seen as totally non correlated functions, and the base function will not consider as overriden.
example::
**
class A
{
public:
virtual void fun(..)const{}
};
class B:public A
{
public:
void fun(..){} //violation
};
**
Related
I struggle creating derived classes and passing method pointers from it to the base class, so that a function declared in the base class may call it (call the function of the derived class via interface).
The goal is to create derived classes to bring their own ressources and functions, but the call of a function declared there should be possible by calling one of them in the function the base class provides. For this i need to pass a member function pointer of the derived down to the base class.
Here's what I tried:
class KeyFunction
{
void(*KeyFunction::KeyFuncPtr)() = nullptr; //pointer to a method of this class to store standard behavior for call
public:
KeyFunction(void(*KeyFunction::KeyFunc)()) : KeyFuncPtr(KeyFunc) {} //constructor which takes in standard behavior
void func() //standard call of the function
{
if(KeyFuncPtr)KeyFuncPtr(); //call with ensurance there's something to be called
}
void operator()() //make KeyFunction class callable
{
func();
}
};
class customRessource{
public:
string up = "UP";
string down = "DOWN";
};
class customKeyFunc : public KeyFunction
{
customRessource& r;
public:
void moveup() //possible behavior
{
cout << r.up;
}
void movedown()
{
cout << r.down;
}
customKeyFunc( void(*customKeyFunc::KeyFunc)() ) :KeyFunction( ( void(*KeyFunction::)() ) (KeyFunc) ){}
};
int main()
{
customKeyFunc Up(&(customKeyFunc::moveup)); //setup functions
customKeyFunc Down(&customKeyFunc::movedown);
Up(); //call functions
Down();
getchar();
return 0;
}
The main function at the end shows the supposed way to use the class .
First of all: my types in the constructors of each class go wild (i tried a lot of search about how to write member pointers right but i'm still not stable with the syntax)
Can someone help me get them right ?
Can I even do this (especially casting down member pointers like i did in the customKeyFunc constructor)? Am I aproaching this the right way or do I think too complicated ?
Thank you in advance for your help !
something like this?
#include <functional>
#include <string>
#include <iostream>
class customResource{
public:
const std::string up = "UP";
const std::string down = "DOWN";
};
class customKeyFunc
{
const customResource& r;
public:
customKeyFunc(const customResource& r) : r(r) {}
void moveup() //possible behavior
{
std::cout << r.up;
}
void movedown()
{
std::cout << r.down;
}
};
int main()
{
customResource r;
customKeyFunc f(r);
auto Up = std::function<void()>(std::bind(&customKeyFunc::moveup, f));
auto Down = std::function<void()>(std::bind(&customKeyFunc::movedown, f));
Up(); //call functions
Down();
return 0;
}
std::function<void()> is a polymorphic functor which will copy any object that:
is movable or copyable, and
implements void operator()
This code gives me error in VS2015 update 1:
error C2893: Failed to specialize function template 'unknown-type
std::invoke(_Callable &&,_Types &&...)'
#include <iostream>
#include <functional>
using std::cout;
class A
{
public:
virtual void init()
{
cout << "A";
};
};
class B
{
public:
virtual void init()
{
cout << "B";
};
};
class C : private A, private B
{
std::function<void()> a_init = &A::init;
std::function<void()> b_init = &B::init;
public:
void call()
{
a_init();
b_init();
}
};
int main()
{
C c;
c.call();
return 0;
}
Any ideas if that's VS compiler is buggy or my code?
EDIT
#include "stdafx.h"
#include <functional>
class A
{
public:
virtual void inita()
{
cout << "A";
};
};
class B
{
public:
virtual void initb()
{
cout << "B";
};
};
class C : private virtual A, private virtual B
{
/*std::function<void()> a_init = &A::init;
std::function<void()> b_init = &B::init;*/
public:
void call()
{
inita();
}
};
You're trying to assign non-static member functions into a std::function taking no arguments. That cannot work, since non-static member functions have an implicit this parameter.
How to solve this depends on what you want to do. If you want to call the stored function on an arbitrary object supplied at call time, you'll need to change the std::function signature:
std::function<void(A*)> a_init = &A::init;
void call()
{
a_init(this); // or some other object of type A on which you want to invoke it
}
[Live example]
If, on the other hand, you want to call it without arguments, you will have to bind an object of type A into the std::function at initialisation:
std::function<void()> a_init = std::bind(&A::init, this);
void call()
{
a_init()
};
[Live example]
Change the function from virtual to static and the code will work. You need a specific instance of a class to call a non-static function.
On the other hand, if you wish to use non-static function, you can add the following constructor:
C(A &a, B &b)
{
a_init = std::bind(&A::init, &a);
b_init = std::bind(&B::init, &b);
}
and then use it in main like this:
A a;
B b;
C c(a, b);
c.call();
EDIT:
If public inheritance is acceptable option, then you can do it even simpler.
Constructor:
C()
{
a_init = std::bind(&A::init, this);
b_init = std::bind(&B::init, this);
}
Usage:
C c;
c.call();
I have a base class
class Shape{
public:
virtual int getArea()=0;
}
I want to change the signature while overriding like this:
class Rectangle : class Shape{
public:
int getArea(int someParameter = 0){
return 0;
}
}
Is it possible somehow to achieve this, as I am using default value for newly added parameter?
The only solution I can see is that you implement both int getArea() and int getArea(int), where one function can call the other (for example int getArea() { return getArea(0); }). You can not have the overload taking an argument have a default argument then.
You need to overload your virtual function. But if you overloaded virtual function, you will get a warning "hides overloaded virtual function"
Solution is override function with native signature and overload it with virtual prefix.
Example:
class A {
virtual void foo(int) {...}
};
class B: public A {
void foo(int i) override {
A::foo(i);
}
virtual void foo(const std::string& str) {
...
}
};
parent class
class Test {
public:
Test(){};
virtual ~Test(){};
void print() { cout<<1<<endl;};
};
sub class .h define
class TestSub: public Test {
public:
TestSub();
virtual ~TestSub();
};
sub class .cpp implements
#include "TestSub.h"
TestSub::TestSub() {
}
TestSub::~TestSub() {
}
void TestSub::print(){
cout<<2<<endl;
}
int main(){
TestSub *t=new TestSub();
t->print();
}
why:
..\src\TestSub.cpp:17:21: error: no 'void TestSub::print()' member function declared in class 'TestSub'
You have 2 errors:
First you have to declare you function in TestSub as : void print();
Second you have to specify a return type for you implementation, C++ do not accept default return type such as C, so you must convert your implementation to void TestSub::print() {...}
print() funciton is not declared in TestSub class.
class TestSub: public Test {
public:
TestSub();
void print(); // add declaration.
virtual ~TestSub();
};
I guess you also intended to make Test::print virtual?
class Test {
public:
Test(){}
virtual ~Test(){}
virtual void print() { std::cout << 1 << std::endl;}
};
If you don't specify the return type C defaults to int as return type of a function. Which doesn't match the void return type of the declaration in the class.
#include<iostream>
using namespace std;
class Abs
{
public:
virtual void hi()=0;
};
class B:public Abs
{
public:
void hi() {cout<<"B Hi"<<endl;}
void bye() {cout<<"B Bye"<<endl;}
};
class C:public Abs
{
public:
void hi() {cout<<"C Hi"<<endl;}
void sayonara() {cout<<"C Sayonara"<<endl;}
};
int main()
{
Abs *bb=new B;
bb->bye();
Abs *cc=new C;
cc->sayonara();
}//main
The compiler says
test2.cpp: In function ‘int main()’:
test2.cpp:26: error: ‘class Abs’ has no member named ‘bye’
test2.cpp:28: error: ‘class Abs’ has no member named ‘sayonara’
Because of this problem, I'll have to add functions to the Abs class each time I create a new derived class which inherits from it (Upcasting is compulsory for me to do. The program I'm planning requires it to be so). I don't want to touch the base class once it's created.
Doesn't this problem violate the principle that once you make a base class, you won't have to modify it ever. Any way to resolve this problem?
p.s: I've seen the factory design pattern and the prototype design patterns, but both of them can't seem to be able to solve it.
This is defeating the purpose of inheritance and abstract interfaces. bye and sayonara both do the same thing (saying goodbye), only in different languages. This means you should have an abstract say_goodbye method that gets overridden for subclasses. I suppose this is a simplified example, so maybe you could describe your actual scenario so we can provide more specific help.
Edit If you want to create a copy of the derived class through an abstract interface, check out this question. If you want to explicitly access the different attributes of your subclasses, you should be asking your self if subclassing es even appropriate here, since your classes don't seem to have much in common.
Well, i'm not sure to understand exactly what you want (and why you want it that way) but:
int main()
{
Abs *bb=new B;
static_cast<B*>(bb)->bye();
Abs *cc=new C;
static_cast<C*>(cc)->sayonara();
}//main
Will work.
You just have to be sure that bb is really a B* before you static_cast.
You may also use dynamic_cast which will return a null pointer if bb is not of the correct type.
int main()
{
B *bb = new B;
bb->bye();
C *cc=new C;
cc->sayonara();
}//main
This way modifications in the base class are no longer needed :)
Dynamic casting is a sensible option. If you're religious about dynamic casts, you can use the visitor design pattern:
struct Abs;
struct B;
struct C;
struct Visitor
{
virtual ~Visitor() {}
// Provide sensible default actions
virtual void visit(Abs&) const { throw "not implemented"; }
virtual void visit(B& b) const { visit(static_cast<Abs&>(b)); }
virtual void visit(C& c) const { visit(static_cast<Abs&>(c)); }
};
struct Abs
{
virtual ~Abs() {}
virtual void hi() = 0;
virtual void accept(Visitor const& v) { v.visit(*this); }
};
struct B : Abs
{
void hi() { ... }
void accept(Visitor const& v) { v.visit(*this); }
void bye() { ... }
};
struct C : Abs
{
void hi() { ... }
void accept(Visitor const& v) { v.visit(*this); }
void sayonara() { ... }
};
struct DoSayonara : Visitor
{
void visit(C& c) const { c.sayonara(); }
};
struct DoBye : Visitor
{
void visit(B& b) const { b.bye(); }
};
struct ByeOrSayonara : Visitor
{
void visit(B& b) const { b.bye(); }
void visit(C& c) const { c.sayonara(); }
};
and then you use
Abs* b = new B(); Abs* c = new C();
b->accept(DoSayonara()); // Throw an exception
c->accept(DoSayonara()); // Do what is expected
Do this only when you really need it.
If upcasting is compulsory and you need to call methods defined in the subclasses then You're Doing It Wrong.
However, at a given point in time, you either know that an object is a specific subclass, in which case you can dynamically cast to that type, or you don't and can't be sure you can call the function.
Assuming this is related to your other question, I've tried to explain a way to implement that particular problem in a different manner there.