I'm wondering if the following is possible. I wanted my derived class dA to change func() to be pure virtual so that any classes derived from dA must implement func().
Code similar to below compiles without complaint under MSVC even though ddA does not implement func().
The compiler does complain about the below code (see comments). So my question now becomes: is this a standards-compliant way to achieve what I want?
class A {
public:
virtual void func() { /* Some base implementation. */ }
}
class dA : public A {
public:
void func() override = 0; // Is this valid?
}
class ddA : public dA {
}
Pure virtual function should be declared in parent class. Consider the code below:
'''
class Shape {
public:
Shape(int init_x, int init_y) : x(init_x), y(init_y) {}
virtual void scale(int s) = 0;
virtual void print() = 0;
protected:
int x;
int y;
};
These functions should be implemented in children:
class Rect : public Shape {
public:
Rect(int init_x, int init_y, int w, int h);
virtual void scale(int s) { //implementation }
virtual void print() { //implementation }
private:
int width;
int height;
};
However you don't have to implement virtual functions in subclasses since it had been implemented in super class:
Pure virtual function make your class abstract so you can't use its instances.
Related
I have got myself into a strange issue now. Ill write a really simplified version of the same.
class Base
{
public:
virtual int func1()=0;
virtual int func2()=0;
protected:
int n;
};
class der1: public Base
{
// implements the virtual functions of the base and uses the protected data
// members of the base.
};
class der2: public Base
{
// implements the virtual functions of the base and uses the protected data
// members of the base.
}
Now the problem.... both der1 and der2 implements the virtual functions of base pretty much the same way. But some other classes (der3, der4) has their own implementations. But still need to inherit from base.
How do i refactor the code to remove the code duplication in an oop manner?
Here's one solution using an intermediate layer of another abstract base class:
class Base12 : public Base {
protected:
int commonFuncStuffA() {
// Commonly used stuff
}
int commonFuncStuffB() {
}
};
class der1: public Base12
{
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = somethingElse;
}
};
class der2: public Base12
{
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = commonFuncStuffB();
}
};
What I'd do for real production code design looks a bit different though.
Declare an interface for the pure virtual functions
struct IMyInterface {
virtual int func1() = 0;
virtual int func2() = 0;
virtual ~IMyInterface {}
};
Provide a abstract base class with the commonly used data members and functions
class BaseImpl : public IMyInterface {
protected:
int n;
int commonFuncStuffA() {
// Commonly used stuff
}
int commonFuncStuffB() {
// Commonly used stuff
}
};
Provide implementations of the interface in the finally derived classes
class der1: public BaseImpl {
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = somethingElse;
}
};
class der2: public BaseImpl {
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = commonFuncStuffB();
}
};
class der3: public IMyInterface {
public:
virtual int func1() {
// Some completely different implementation of the interface
}
virtual int func2() {
// Some completely different implementation of the interface
}
};
class der4: public IMyInterface {
public:
virtual int func1() {
// Some completely different implementation of the interface
}
virtual int func2() {
// Some completely different implementation of the interface
}
};
Option 1
You may consider using your most common implementation in the Base class. The main feature or drawback of this method is that the base class would no longer be abstract. If this is a problem, go to option 2.
Maybe you can even cope with differences in the derived classes by using the template method pattern to extract the differences in protected virtual functions invoked by the template method.
In anyway, for derived classes that need a completely different appoach, you'd just override the the Base class' method.
class Base
{
public:
virtual int func1();
virtual int func2()=0;
protected:
virtual void f1_specific_part1()=0;
virtual void f1_specific_part2()=0;
int n;
};
int Base::func1() { // common skeleton of the algorithm
...
f1_specific_part1();
...
f1_specific_part2();
...
}
class Der1: public Base
{
protected:
void f1_specific_part1() override; // Implements the specific variation
virtual void f1_specific_part2() override;
};
Option 2
You may consider to factorize the common code of the derived classes into a protected method of the Base class.
The override of the pure virtual function would then just call the base class protected common function (for der1 and der2) or just use their own implementation that is completely different (for der3 and der4).
class Base
{
public:
virtual int func1()=0;
virtual int func2()=0;
protected:
int common_part1_funct1(); // implements some common parts
int common_part2_funct1();
int n;
};
class Der1: public Base
{
...
int func1() override {
common_part1_funct1();
...
common_part2_funct1();
...
}
};
Option 3 ?
Important remark: My answer assumes that there are many commonalities between most of the derived classes. However if you have only a small subset of derived classes that share some commonalities, then the answer of Evg would be would be more appropriate.
The idea with Base12 is:
struct Base {
virtual int func1() = 0;
virtual int func2() = 0;
};
struct Base12 : Base {
protected:
int func12();
};
struct Der1: public Base12 {
virtual int func1() {
return func12();
virtual int func2() {
return func12();
};
struct Der2: public Base12 {
virtual int func1() {
return func12();
virtual int func2() {
return func12();
};
Please refer the following example.
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1();
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
In the above example, for all other entities deriving from IBase needs to implement BaseMethod1() and BaseMethod2().Because of which lots of code duplication is happening? Is there anyway where we can avoid redundant implementation of IBase methods in entities deriving from it?
You can use virtual inheritance in combination with a default base implementation class to encapsulate your default base behavior, and have it be only inherited by the concrete classes you want, like follows:
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : virtual public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class BaseImpl : virtual public IBase
{
public:
virtual void BaseMethod1()
{
...
}
virtual void BaseMethod2()
{
...
}
}
class Entity1 : public IEntity1, public BaseImpl
{
public:
Entity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
There is, however, a runtime cost associated with virtual inheritance. Multiple inheritance also comes with some structural issues, e.g. base class construction.
You can even have some fun with template classes to make your class composition more modular:
template<typename TEntity, typename TBaseImpl>
class ConcreteEntity: public TEntity, public TBaseImpl
{
public:
ConcreteEntity() {}
};
class ConreteEntity1 : public ConcreteEntity<IEntity1, BaseImpl>
{
public:
ConreteEntity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//ConreteEntity1 Methods
void Method1();
void Method2();
};
You could make a function that is called in BaseMethod1() implementations that are the same.
Something like this:
void BaseMethod1_common();
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1() { BaseMethod1_common(); }
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
First of all IBase deserves a virtual destructor.
Declare it pure virtual and define IBase:BaseMethod1() and
IBase::BaseMethod1().
If your intention is to hide implementation, then the only option would be to release the code as a library and then share only the header file among the other developers.
Implementing a global function, or using multiple inheritance as suggested still mean that your implementation is exposed.
However, if the intent is to reduce coupling among the various classes, there's another option :
Create a class that has the actual shared implementation, and then another class which will be an interface to it.
This interface class will then be the base class for other derived entities.
Example code is shown below :
//First Header and Cpp file
class Base_private
{
public:
BaseImpl(arguments);
~BaseImpl();
void BaseMethod1() {
//Implementation
}
void BaseMethod2() {
//Implementation
}
};
//Second Header and Cpp file
class BaseInterface
{
public:
BaseInterface(arguments);
~BaseInterface();
void BaseMethod1() {
m_pBase->BaseMethod1();
}
void BaseMethod2() {
m_pBase->BaseMethod2();
}
private:
Base_private* m_pBase;
};
class Entity : public BaseInterface
{
public:
Entity(arguments);
~Entity();
void Method1();
void Method2();
};
I'm not happy with the question title, but I couldn't describe it well. I'm putting implementation in the class declarations for sake of brevity.
I have a class like this:
class VisibleObject {
public:
void draw(sf::RenderWindow& rw) {
rw.draw(*shape.get());
}
virtual void setSize(sf::Vector2f) = 0;
protected:
std::shared_ptr<sf::Shape> shape;
}
sf::Shape is an abstract class. Then I have a derived class like so:
class Brick : VisibleObject {
Brick() {
shape.reset(new sf::RectangleShape());
}
void setSize(sf::Vector2f newSize) {
std::dynamic_pointer_cast<sf::RectangleShape>(shapes).get()->setSize(newSize);
}
}
sf::RectangleShape() is a concrete class that inherits from sf::Shape and setSize() is defined for it, not sf::Shape, which is why I need to cast.
Of course, I need to do some error handling, in the case that the dynamic cast fails and returns an empty shared_ptr.
I'm doing this because I wanted to be able to define the draw method just once, since in this simple game, every object will draw their member this way. Originally I left the shape out of the base class, and e.g. Brick would just have its own private sf::RectangleShape that could get instantiated on the stack; which was clean, but then the draw method had to be re-written for each object type.
This works, but is uglier to work with and introduces heap allocation. I also have shared_ptr overhead (I would have used unique_ptr, but I needed dynamic casting).
Is this the most appropriate way of doing what I'm trying to do?
It might be preferable to keep the interface an interface, and not start mandating implementation details. So just have an empty base class like so:
class VisibleObject
{
public:
~VisibleObject() {}
virtual void draw(sf::RenderWindow & window) = 0;
virtual void setSize(sf::Vector2f const & size) = 0;
};
You can stick the shape storage into the concrete class that implements this interface.
Moreover, Shape should provide a virtual resize method:
class Shape
{
public:
virtual ~Shape() {}
virtual void resize(sf::Vector2f const & size) = 0;
};
Now you can make, say, a VisibleShapeObject as an intermediate base class:
class VisibleShapeObject : public VisibleObject
{
public:
virtual void draw(sf::RenderWindow & window) override final
{
window.draw(*shape_);
}
virtual void setSize(sf::Vector2f const & size) override final
{
shape_->resize(size);
}
protected:
std::shared_ptr<Shape> shape_; // or unique_ptr<Shape>
};
Instead of mandating storage in std::shared_ptr<sf::Shape>, why not simply introduce a means of retrieving an sf::Shape& from the concrete class?
class VisibleObject {
virtual sf::Shape& getShape() = 0;
public:
void draw(sf::RenderWindow& rw) {
rw.draw(getShape());
}
virtual void setSize(sf::Vector2f) = 0;
};
class Brick : VisibleObject {
sf::RectangleShape shape;
sf::Shape& getShape() override { return shape; }
public:
void setSize(sf::Vector2f newSize) override {
shape.setSize(newSize);
}
};
It seems ridiculous to store via a pointer to base, introducing indirections and downcasts and reference count overhead, when you could just store a plain old member. In fact, if I'm understanding the problem correctly, you could probably use a template to generate concrete classes and avoid a lot of boilerplate:
class VisibleObject {
public:
virtual ~VisibleObject() {}
virtual void draw(sf::RenderWindow&) = 0;
virtual void setSize(sf::Vector2f) = 0;
};
template <typename Shape>
class VisibleConcreteObject : public VisibleObject {
Shape shape;
public:
void draw(sf::RenderWindow& rw) override /* final? */ {
rw.draw(shape);
}
void setSize(sf::Vector2f newSize) override /* final? */ {
shape.setSize(newSize);
}
};
typedef VisibleConcreteObject<sf::RectangleShape> Brick;
You haven't shared everything you are trying to do, but this it one way:
template<ShapeT>
class VisibleObject {
public:
void draw(sf::RenderWindow& rw) {
rw.draw(*shape.get());
}
virtual void setSize(sf::Vector2f) = 0;
protected:
std::shared_ptr<ShapeT> shape;
void reset(ShapeT* shape) {
this->shape = shape;
}
}
class Brick : VisibleObject<sf::RectangleShape> {
Brick() {
shape.reset(new sf::RectangleShape());
}
void setSize(sf::Vector2f newSize) {
shape->setSize(newSize);
}
}
There may be reasons why this doesn't work for you, but without more insight, I couldn't guess at what.
Why is it that in the code below the compiler complains that PureAbstractBase is an ambiguous base class of MultiplyInheritedClass? I realize I have two copies of the PureAbstractBase in MultiplyInheritedClass and that FirstConreteClass and SecondConreteClass should be derived virtually because they're the middle row of the diamond (and that does indeed fix the problem with the code below). But even though I have two copies of the interface why is it that the code in MultiplyInheritedClass does not just override both and unambiguously pick the interface class defined in MultiplyInheritedClass?
#include <iostream>
using namespace std;
class PureAbstractBase {
public:
virtual void interface() = 0;
};
// I know that changing the following line to:
// class FirstConcreteClass : public virtual PureAbstractBase {
// fixes the problem with this hierarchy
class FirstConcreteClass : public PureAbstractBase {
public:
virtual void interface() { implementation(); }
private:
void implementation() { cout << "This is object FirstConcreteClass\n"; }
};
// I know that changing the following line to:
// class SecondConcreteClass : public virtual PureAbstractBase {
// fixes the problem with this hierarchy
class SecondConcreteClass : public PureAbstractBase {
public:
virtual void interface() { implementation(); }
private:
void implementation() { cout << "This is object SecondConcreteClass\n"; }
};
class MultiplyInheritedClass : public FirstConcreteClass,
public SecondConcreteClass {
public:
virtual void interface() { implementation(); }
private:
void implementation() { cout << "This is object MultiplyInheritedClass\n"; }
};
Further, why do I not have issues with the following hierarchy? Doesn't the ConcreteHandler class have three copies of the AbstractTaggingInterface in this case? So why doesn't it have the same issue as the example above?
#include <iostream>
using namespace std;
class AbstractTaggingInterface {
public:
virtual void taggingInterface() = 0;
};
class FirstAbstractHandler : public AbstractTaggingInterface {
public:
virtual void taggingInterface() { cout << "FirstAbstractHandler\n"; }
virtual void handleFirst() = 0;
};
class SecondAbstractHandler : public AbstractTaggingInterface {
public:
virtual void taggingInterface() { cout << "SecondAbstractHandler\n"; }
virtual void handleSecond() = 0;
};
class ThirdAbstractHandler : public AbstractTaggingInterface {
public:
virtual void taggingInterface() { cout << "ThridAbstractHandler\n"; }
virtual void handleThird() = 0;
};
class ConcreteHandler : public FirstAbstractHandler,
public SecondAbstractHandler,
public ThirdAbstractHandler {
public:
virtual void taggingInterface() = { cout << "ConcreteHandler\n"; }
virtual void handleFirst() {}
virtual void handleSecond() {}
virtual void handleThird() {}
};
I am trying to wrap my head around all of this because I had a conversation with a colleague recently where he claimed that if you were inheriting from pure virtual classes (interfaces) without any data members then virtual inheritance was not necessary. I think understanding why the former code example does not work and the latter does would go a long way to getting this straight in my head (and clear up what exactly he meant by his comment). Thanks in advance.
You need virtual inheritance to overcome the diamond-ambiguity:
class FirstConcreteClass : public virtual PureAbstractBase { ... };
class SecondConcreteClass : public virtual PureAbstractBase { ... };
Long-winded explanation: Suppose you have this:
// *** Example with errrors! *** //
struct A { virtual int foo(); };
struct B1 : public A { virtual int foo(); };
struct B2 : public A { virtual int foo(); };
struct C: public B1, public B2 { /* ... */ }; // ambiguous base class A!
int main() {
A * px = new C; // error, ambiguous base!
px->foo(); // error, ambiguous override!
}
The inheritance of the virtual function foo is ambiguous because it comes in three ways: from B1, from B2 and from A. The inheritance diagram forms a "diamond":
/-> B1 >-\
A-> ->C
\-> B2 >-/
By making the inheritance virtual, struct B1 : public virtual A; etc., you allow any baseclass of C* to call the correct member:
struct A { virtual int foo(); };
struct B1 : public virtual A { virtual int foo(); };
struct B2 : public virtual A { virtual int foo(); };
struct C: public B1, public B2 { virtual int foo(); };
We must also define C::foo() for this to make sense, as otherwise C would not have a well-defined member foo.
Some more details: Suppose we now have a properly virtually-inheriting class C as above. We can access all the various virtual members as desired:
int main() {
A * pa = new C;
pa->foo(); // the most derived one
pa->A::foo(); // the original A's foo
B1 * pb1 = new C;
pb1->foo(); // the most derived one
pb1->A::foo(); // A's foo
pb1->B1::foo(); // B1's foo
C * pc = new C;
pc->foo(); // the most derived one
pc->A::foo(); // A's foo
pc->B1::foo(); // B1's foo
pc->B2::foo(); // B2's foo
pc->C::foo(); // C's foo, same as "pc->foo()"
}
Update: As David says in the comment, the important point here is that the intermediate classes B1 and B2 inherit virtually so that further classes (in this case C) can inherit from them while simultaneously keeping the inheritance from A unambiguous. Sorry for the initial mistake and thanks for the correction!
Your first example fails because the compiler cannot disambiguate between the three implementations of implementation(). You are overriding that method in MultiplyInheritedClass, which actually overrides both FirstConcreteClass::implementation and SecondConcreteClass::implementation (once virtual, always virtual). However, both virtual calls still exist in the interface of MultiplyInheritedClass, which makes the call ambiguous at the call site.
The reason that your example works without virtual inheritance is that there is no conflicting implementation of the common base class. Put another way:
class Base
{
public:
void DoSomething() {
std::cout << "TADA!";
}
}
class One : public Base
{
//...
}
class Two : public Base
{
//...
}
class Mixed : public One, public Two
{
//...
}
int main()
{
Mixed abc;
abc.DoSomething(); //Fails because the compiler doesn't know whether to call
// One::DoSomething or Two::DoSomething, because they both
// have implementations.
//In response to comment:
abc.One::DoSomething(); //Succeeds! You removed the ambiguity.
}
Because your example has all pure virtual functions, there's no multiple implementations which the compiler needs to disambiguate. Therefore, only one implementation exists, and the call is unambiguous.
I tried both of the question codes and they worked fine when instantiating an object of the multi-inherited class. It didn't work only with polymorphism, like this for example:
PureAbstractBase* F;
F = new MultiplyInheritedClass();
And the reason is clear: it doesn't know to which copy of the Abstract base class it should be linked (sorry for bad expressions, I understand the idea but can't express it). And since inherting virtaully makes only one copy exist in the derived class, then it's fine.
Also the code of Billy ONeal is not clear at all, what should we place instead of the comments?
If we place:
public:
void DoSomething()
{ std::cout << "TADA!"; }
it works fine, because of no virtuality.
I work on Visual Studio 2008.
Why not do it like this (suggested in Benjamin Supnik's blog entry):
#include <iostream>
class PureAbstractBase {
public:
virtual void interface() = 0;
};
class FirstConcreteClass : public PureAbstractBase {
public:
virtual void interface() { implementation(); }
private:
void implementation() { std::cout << "Fisrt" << std::endl; }
};
class SecondConcreteClass : public PureAbstractBase {
public:
virtual void interface() { implementation(); }
private:
void implementation() { std::cout << "Second" << std::endl; }
};
class MultiplyInheritedClass : public FirstConcreteClass,
public SecondConcreteClass
{
public:
virtual void interface() { implementation(); }
private:
void implementation() { std::cout << "Multiple" << std::endl; }
};
int main() {
MultiplyInheritedClass mic;
mic.interface();
FirstConcreteClass *fc = &mic; //disambiguate to FirstConcreteClass
PureAbstractBase *pab1 = fc;
pab1->interface();
SecondConcreteClass *sc = &mic; //disambiguate to SecondConcreteClass
PureAbstractBase *pab2 = sc;
pab2->interface();
}
which gives:
Multiple
Multiple
Multiple
This way:
no virtual bases are involved (do you really need them?)
you can call the overriden function via a an instance of the MultiplyInheritedClass
ambiguity is removed by a two-stage conversion
I have a class as follows:
Class A
{
virtual int doSomethingCool() = 0;
};
Class B : public A
{
int doSomethingCool();
};
Now the problem likes , I have a set of classes whcih are dependent on A as interface. I need to change the prototype of the function for one of the derived classes. i.e. i need to pass it a parameter.
Class C: public A
{
int doSomethingCool(int param);
};
Any suggestions how i can achieve this ?
No, you don't need to add it to the base class.
class A
{
public:
virtual int doSomethingCool() = 0 {}
};
class B : public A
{
public:
int doSomethingCool() {return 0;}
};
class C: public A
{
private:
int doSomethingCool(); // hide base class version!
public:
int doSomethingCool(int param) {return param;}
};
You can still call doSomethingCool() if done through a base class pointer:
C c;
//c.doSomethingCool (); // doesn't work, can't access private member
c.doSomethingCool (42);
A &a = c;
a.doSomethingCool ();
//a.doSomethingCool (42); // doesn't work, no member of A has that signature
Add it to the interface and default it to call the existing method. You don't have to do the default but don't make it pure otherwise all derived classes will have to implement. It might be better to leave it undefined or to throw. Depends on what you want to achieve.
class A
{
public:
virtual int doSomethingCool() = 0;
virtual int doSomethingCool(int param) {doSomethingCool()};
};
Make the function doSomethingCool() take the int parameter in A.
class A
{
public:
virtual void doSomethingCool(int param) = 0;
};
There's no problem. You can do it. The only caveat is that it will not be treated as an override of the base class virtual function.
class A
{
public:
virtual void doSomethingCool() = 0;
};
class B : public A
{
public:
void doSomethingCool();
};
class C: Public A
{
public:
void doSomethingCool(int param);
};
int main(){}
So while technically possible, you may really want to relook at the design of your interface class A.
One option may be to provide a default argument to A::doSomethingCool
virtual void doSomethingCool(int = 0) = 0;
This isn't syntactically correct C++.
No you can't change a prototype. How would it be used? What would be the value of the param if the non-parametric version would be called?
I would have introduced another, more specific, interface:
struct A
{
virtual int doSomethingCool() = 0;
};
struct A_specific : A
{
virtual int doSomethingCoolWithThis(int i) = 0;
};
class ConcreteA : public A
{
int doSomethingCool() { return 0; }
};
class ConcreteA_specific : public A_specific
{
int doSomethingCool() { return 0; }
int doSomethingCoolWithThis(int param) { return param; }
};
Then I would program to the correct interface:
int main()
{
const A& a1 = ConcreteA();
const A_specific& a2 = ConcreteA_specific();
a1.doSomethingCool();
a2.doSomethingCool();
a2.doSomethingCoolWithThis(2);
}
Just to give you another idea ;-)
Good luck!