What happens when a class inherits from multiple abstract classes when 2 or more of them have a function with the same name, return type, and arguments?
Assuming all functions here are virtual
Thanks
class C inherits from A and B at the same time and both A & B have virtual void func(int h);
If this is what you mean,
#include <iostream.h>
class A
{
public:
virtual void a_show()=0;
virtual void show()
{
cout<<"A";
}
};
class B
{
public:
virtual void b_show()=0;
virtual void show()
{
cout<<"B";
}
};
class C : public A, public B
{
virtual void a_show()
{}
virtual void b_show()
{}
};
void main()
{
C s;
s.show();
}
The code gives an error with VC++ like
error C2385: 'C::show' is ambiguous
You need to declare show like this :
#include <iostream.h>
class A
{
public:
virtual void a_show()=0;
virtual void show()
{
cout<<"A";
}
};
class B
{
public:
virtual void b_show()=0;
virtual void show()
{
cout<<"B";
}
};
class C : public A, public B
{
public:
virtual void a_show()
{}
virtual void b_show()
{}
void show()
{
cout<<"C";
}
};
void main()
{
C s;
s.show();
}
This sure will give C
C++ also allows to pick an inherited virtual member function (IVMF) as well, so you don't need to override an IVMF. Borrowing the example from mihsathe, we can do the following:
class C : public A, public B {
public:
virtual void a_show() { }
virtual void b_show() { }
using B::show;
// using A:show; // If you want to use show() from A
};
Related
if I have the following code:
class A
{
public:
virtual void Yo();
}
class B : public A
{
public:
virtual void Yo() override;
}
Is there a way to force B to implement method Yo in A? Like an interface or more specifically (in this case) an abstract?
My full code is here:
BaseObject.h
#pragma once
namespace Game
{
namespace Model
{
namespace Graphic
{
class BaseObject
{
public:
int Width;
int Height;
float X;
float Y;
float Z;
virtual void SetUp() = 0;
virtual void Reset() = 0;
};
}
}
}
Player.cpp
#include "pch.h"
#include "Abstract\BaseObject.h"
using namespace Game::Model::Graphic;
class Player : public BaseObject
{
public:
Player();
~Player();
//virtual void SetUp();
//virtual void Reset() override;
};
in A make Yo pure virtual
virtual void Yo() = 0;
a complete example
#include <iostream>
struct A
{
virtual void Yo() = 0;
};
struct B : A
{
virtual void Yo() { std::cout << "I'm B\n"; }
};
int main()
{
B b;
b.Yo();
return (0);
}
if B doesn't implement Yo this will not compile.
The override keyword it's not needed in this case.
You have to take pointer of the base class to implement virtual functions in C++. This seems quite obvious. But i think we have missed that. The most basic example is given below.
#include <iostream>
using namespace std;
class base {
public:
virtual void vfunc() {
cout << "This is base's vfunc().\n";
}
};
class derived1 : public base {
public:
void vfunc() {
cout << "This is derived1's vfunc().\n";
}
};
int main()
{
base *p, b;
derived1 d1;
// point to base
p = &b;
p->vfunc(); // access base's vfunc()
// point to derived1
p = &d1;
p->vfunc(); // access derived1's vfunc()
return 0;
}
So I have two classes. One has only purely virtual functions. THe other implements those functions and is derived from the first class.
I get that i cant instantiate the first class. But when I try to create an object of the second class it fails as well.
This is how my second class looks in general:
class SecondClass : public FirstClass
{
public:
SecondClass();
virtual ~SecondClass(void);
void Foo();
void Bar();
}
Implementation:
SecondClass::SecondClass()
{...}
SecondClass::~SecondClass(void)
{...}
void SecondClass::Foo()
{...}
void SecondClass::Bar()
{...}
This how I instantiate it and get the Error:
SecondClass mSecClass;
Where am I going wrong here?
FirstClass.h
class FirstClass
{
public:
FirstClass(void);
virtual ~FirstClass(void);
virtual void Foo() = 0;
virtual void Bar() = 0;
};
You need to define the ~FirstClass() destructor and leave out its constructor
class FirstClass
{
public:
virtual ~FirstClass(void) {} // or use C++11 = default syntax
virtual void Foo() = 0;
virtual void Bar() = 0;
};
class SecondClass : public FirstClass
{
public:
SecondClass();
virtual ~SecondClass(void);
void Foo();
void Bar();
};
SecondClass::SecondClass() {}
SecondClass::~SecondClass(void) {}
void SecondClass::Foo() {}
void SecondClass::Bar() {}
int main()
{
SecondClass mSecClass;
}
Live Example.
Define every function you declare, except for pure virtuals(virtual void foo() = 0).
try the below code:
#include<iostream>
using namespace std;
class FirstClass
{
public:
FirstClass()
{
//
}
virtual ~FirstClass();
virtual void Foo();
virtual void Bar();
};
FirstClass::~FirstClass()
{
//
}
void FirstClass::Foo()
{
//
}
void FirstClass::Bar()
{
//
}
class SecondClass : public FirstClass
{
public:
SecondClass();
virtual ~SecondClass(void);
void Foo();
void Bar();
};
SecondClass::SecondClass(){
//
}
SecondClass::~SecondClass(void)
{//
}
void SecondClass::Foo()
{//
}
void SecondClass::Bar()
{//
}
int main()
{
SecondClass name;
return 0;
}
Is it possible to have a derived class to have two sets of the same virtual functions as the base class? I'm looking to do something like the following. The idea being able to choose between two sets of function pointers.
class Base
{
virtual void func1;
virtual void func2;
};
class Derived: Base
{
float somemember;
void somefunction()
{
Base* func = this->derived_functions1;
}
class derived_functions1
{
virtual void func1()
{
return somemember*100;
}
virtual void func2;
};
class derived_functions2
{
virtual void func1;
virtual void func2;
};
};
class Base
{
public:
virtual void func1();
virtual ~Base(){}
};
struct Impl1 : Base
{
void func1() override {}
};
struct Impl2 : Base
{
void func1() override {}
};
struct Derived : Base
{
Derived(std::unique_ptr<Base> implementation) :
impl(std::move(implementation))
{}
void func1() override { impl->func1(); }
void changeImpl(std::unique_ptr<Base> implementation)
{
impl = std::move(implementation);
}
private:
std::unique_ptr<Base> impl;
};
Not the way you did. But you can make both the inner class derived_functionsX to be themseves public: Base, than have your main Derived to contain a std::unique_ptr<Base> ptryou can set to new derived_functions1 or new derived_functions2
and implement in Derived func1 and func2 to call ptr->func1() and ptr->func2().
For all that to work properly, Base must also have a virtual ~Base() {} otherwise no proper deletion can be done.
In this example, it won't compile, since derived_function1 and derived_functions2 aren't inheriting from Base.
But you could have something like this:
class Base
{
virtual void func1();
virtual void func2();
};
class Wrapper {
public:
Wrapper(int arg)
{
switch(arg)
{
case 1:
b = new derived_functions1;
break;
case 2:
b = new derived_functions2;
break;
default:
cout << "bad value of arg" << arg << endl;
exit(1);
}
}
~Wrapper()
{
delete b;
}
Base* GetClass()
{
return b;
}
private:
Base *b;
class derived_functions1: public Base
{
virtual void func1();
virtual void func2();
};
class derived_functions2: public Base
{
virtual void func1();
virtual void func2();
};
};
Short answer: No. A class can override inherited virtual functions only once.
However, there is a design pattern that exchanges function's behavior on the fly, called Strategy Pattern. In short: the class that has exchangeable behavior has a pointer to a Strategy base class that defines the interface for that behavior. It is populated with concrete Strategy classes. The function that has different behavior just delegates its calls to the Strategy pointer. Here's an example, tailored to your question:
class Base {
public:
virtual void func1() = 0;
virtual void func2() = 0;
virtual ~Base(){}
};
#include <iostream>
#include <memory>
class Derived : public Base
{
struct F1Strategy {
virtual void f1Impl() = 0;
virtual ~F1Strategy() {}
};
struct Impl1 : F1Strategy {
void f1Impl() override { std::cout << "one!\n"; }
};
struct Impl2 : F1Strategy {
void f1Impl() override { std::cout << "two?\n"; }
};
std::unique_ptr<F1Strategy> f1Strategy;
public:
Derived()
: f1Strategy(new Impl1())
{}
void func1() override { f1Strategy->f1Impl(); }
void func2() override {
static std::unique_ptr<F1Strategy> otherStrategy(new Impl2());
f1Strategy.swap(otherStrategy);
}
};
int main() {
std::unique_ptr<Base> pb(new Derived());
pb->func1(); // ==> one!
pb->func2(); //swap
pb->func1(); // ==> two?
pb->func1(); // ==> two?
pb->func2(); //swap
pb->func1(); // ==> one!
}
See it in action: http://ideone.com/zk3UTI
I am new to Design Pattern, and I'm trying the first example of (Head First Design Patterns) but I'm trying to code it in C++. I can't compile my code! I don't know why. Here's my code.
#include <iostream>
using namespace std;
class QuackBehavior
{
public:
virtual void quack();
virtual ~QuackBehavior();
};
class Quack : public QuackBehavior
{
public:
void quack()
{
cout<<"Quacking"<<endl;
}
};
class MuteQuack : public QuackBehavior
{
public:
void quack()
{
cout<<"<<< Silence >>>"<<endl;
}
};
class Squeak : public QuackBehavior
{
public:
void quack()
{
cout<<"Squeak"<<endl;
}
};
class FlyBehavior
{
public:
virtual void fly();
virtual ~FlyBehavior();
};
class FlyWithWings : public FlyBehavior
{
public:
void fly()
{
cout<<"I'm flying"<<endl;
}
};
class FlyNoWay : public FlyBehavior
{
public:
void fly()
{
cout<<"I can't fly"<<endl;
}
};
class Duck
{
public:
FlyBehavior *flyBehavior;
QuackBehavior *quackBehavior;
void display();
void performFly()
{
flyBehavior->fly();
}
void performQuack()
{
quackBehavior->quack();
}
};
class MallardDuck : public Duck
{
public:
MallardDuck()
{
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
};
int main()
{
Duck *mallard = new MallardDuck;
cout<<"Test"<<endl;
mallard->performFly();
// mallard->performQuack();
return 0;
}
Thanks for your help.
You get a compile error because you have not provided default definitions for functions in class QuackBehavior and class FlyBehavior.
Either you could provide default implementation or make the functions pure virtual.
Make the below two changes and your code should compile fine.
class QuackBehavior
{
public:
virtual void quack(){}
virtual ~QuackBehavior(){}
};
class FlyBehavior
{
public:
virtual void fly(){}
virtual ~FlyBehavior(){}
};
OR
class FlyBehavior
{
public:
virtual void fly() = 0;
};
class QuackBehavior
{
public:
virtual void quack() = 0;
};
This question already has answers here:
Inherit interfaces which share a method name
(5 answers)
Closed 10 years ago.
Have code as below
// A has a virtual function F().
class A
{
public:
virtual void F() {};
};
// The same for B.
class B
{
public:
virtual void F() {};
};
// C inherits A and B.
class C : public A, public B
{
public:
// How to implement the 2 virtual functions with the same name but from
// different base classes.
virtual F() {...}
};
Note that there is a default implementation of F() in the base classes.
Thanks to Jan Herrmann and Spook. Is the below a simpler solution if we have to use some extra helpers?
#include <iostream>
// A has a virtual function F().
class A
{
private:
virtual void A_F() {}
public:
void F() {return A_F();};
};
// The same for B.
class B
{
private:
virtual void B_F() {}
public:
void F() {return B_F();};
};
// C inherits A and B.
class C : public A, public B
{
private:
virtual void A_F() {std::cout << "for A\n";}
virtual void B_F() {std::cout << "for B\n";}
};
int main()
{
C c;
c.A::F();
c.B::F();
return 0;
}
class C_a
: public A
{
virtual void F_A() = 0;
virtual void F() { this->F_A() };
};
class C_b
: public B
{
virtual void F_B() = 0;
virtual void F() { this->F_B() };
};
class C
: public C_a
, public C_b
{
void F_A() { ... }
void F_B() { ... }
};
If I'm remembing right the ISO committee thought about this problem and discussed a change of the language. But then ... somebody found this nice way to solve this problem :-)
Your second solution is better in case your are able to change your class hierarchy. You may have a lock at http://www.gotw.ca/publications/mill18.htm for a description why it is better.
Try this:
#include <cstdio>
class A
{
public:
virtual void F() = 0;
};
class B
{
public:
virtual void F() = 0;
};
class C : public A, public B
{
void A::F()
{
printf("A::F called!\n");
}
void B::F()
{
printf("B::F called!\n");
}
};
int main(int argc, char * argv[])
{
C c;
((A*)(&c))->F();
((B*)(&c))->F();
getchar();
return 0;
}
Take into consideration though, that you won't be able to call F from C's instance (ambiguous call).
Also, F has to be abstract in A and B, otherwise you'll get compilation error:
Error 1 error C3240: 'F' : must be a non-overloaded abstract member function of 'A'