Derived Class Calling Non-Public Base Class Virtual Function - c++

EDITED:
This question has already been asked here
but didn't help in my case. I'm trying to have a hierarchy of classes, with inherited public update() functions. But I want a given derived derived class to call the functionality of all of its base classes before doing its own processing. My actual VS2013 solution consists of an EXE project that references a DLL project, but the simplified code below still produces the error:
// Map.h (in DLL project)
namespace Game2D {
class Map {
public:
explicit Map();
~Map();
void update(double);
protected:
virtual void baseUpdates(double dt) {}
};
}
// Map.cpp (in DLL project)
namespace Game2D {
Map::Map() { }
Map::~Map() {}
void Map::update(double dt) {
baseUpdates(dt);
// Do some base stuf...
}
}
// AutoScrollMap.h (in DLL project)
namespace Game2D {
class AutoScrollMap : public Map {
public:
explicit AutoScrollMap();
~AutoScrollMap();
protected:
virtual void baseUpdates(double) {}
};
}
// AutoScrollMap.cpp (in DLL project)
namespace Game2D {
AutoScrollMap::AutoScrollMap() : Game2D::Map() {}
AutoScrollMap::~AutoScrollMap() {}
void AutoScrollMap::baseUpdates(double dt) {
// Do some stuff...
}
}
// DesertMap.h (in EXE project)
namespace Shooter {
class DesertMap : public Game2D::AutoScrollMap {
public:
explicit DesertMap();
~DesertMap();
protected:
virtual void baseUpdates(double);
};
}
// DesertMap.cpp (in EXE project)
namespace Shooter {
DesertMap::DesertMap() : Game2D::AutoScrollMap() {}
DesertMap::~DesertMap() {}
void DesertMap::baseUpdates(double dt) {
AutoScrollMap::baseUpdates(dt);
// Do more specific stuff...
}
}
This gives me a compiler error of "error C2084: function 'void Game2D::AutoScrollMap::baseUpdates(double)' already has a body". The article above says I can use this syntax to call a function that is being overloaded. However, the base function in its example was public, not protected, and I really want to keep baseUpdates() protected since its not part of the interface.
I thought this problem was a fairly basic use of the OOP inheritance paradigm, so what am I missing? All advice is greatly appreciated!

The method you described has no problem, the problem is in your code. You already implemented Derived2::baseUpdates() inline, then you try to define it again. You should change Derived2 to this:
class Derived2 : public Derived1 {
public:
Derived2() : Derived1() { }
protected:
virtual void baseUpdates();
};
void Derived2::baseUpdates() {
Derived1::baseUpdates();
}
Also your Base constructor is not implemented.

Wow, trying to reduce this code to its simplest form for help actually revealed the problem. I had already put braces "{}" after baseUpdates() in AutoScrollMap.h, hence the "function already has body" error. Looks like you sure can call base virtual functions from derived overrides, even if the base function is not public! Sorry for wasting everybody's time, haha.

Related

Abstract class and inheritance

class MyInterface {
public:
virtual void someFunction()= 0;
};
class X: public MyInterface {
private:
virtual void doThis() {
printf("This X");
}
virtual void doThat() {
printf("That X");
}
public:
void someFunction() {
doThis();
doThat();
}
};
class Y: public MyInterface, private X {
private:
void doThat() {
printf("That Y");
}
};
MyInterface *iface= new Y();
Y->someFunction();
Coming from Java's flavor of OOP, I am trying to wrap my head around the OOP model of C++. I have read this: http://www.gotw.ca/publications/mill18.htm for suggestions how to design interfaces in C++. The above code is a direct application (or a slight variation thereof) of the rule the author expounds. My question is, is the code above going to produce "This X" followed by "That Y"? What I find confusing is that the author recommends using virtual in conjunction with private. My reasoning is, if a function is private, how are we to override it at all?
In the above code, it is granted that Y can be used as the right-hand-side of the assignment, since we derive publicly from the interface. When we call someFunction() on it, since we do not explicitly provide any implementation inside class Y, is it going to use the implementation from class X? Then, provided it does, it looks at doThat() and again uses Ys implementation of it?
The code has a few problems. Here is a working example:
class MyInterface
{
public:
virtual ~MyInterface() { }
virtual void someFunction() = 0;
};
class X : public MyInterface
{
private:
virtual void doThis()
{
printf("This X\n");
}
virtual void doThat()
{
printf("That X\n");
}
public:
void someFunction()
{
doThis();
doThat();
}
};
class Y : public X
{
private:
void doThat()
{
printf("That Y\n");
}
};
int main()
{
MyInterface *iface = new Y();
iface->someFunction();
delete iface;
}
Explanations
You need to use class Y : public X to be able to use the implementation of void X::someFunction()
Unfortunately there is no real interface in C++ and there is only a workaround using pure virtual class. This workaround with two parents has it's own limitations (see bellow). And therefore it is also a good idea to add a destructor to interface definition.
When you use class Y: public MyInterface, private X you need to provide a custom implementation of MyInterface::someFunction(). You have have two parent classes and someFunction() in both parents (X and MyInterface). This is necessary even when there is only one implementation of function. Therefore you need to specify which parent class 'implementation' will be used. Error:
'Y': cannot instantiate abstract class
You also get a error when you remove the interface (try to use the interface from X). The reason is simple, when X is private, the implementation is not public and can not be used as a interface.
'type cast': conversion from 'Y *' to 'MyInterface *' exists, but is inaccessible
You are using class as type in Y->someFunction();
I have no idea, why you can override a private virtual function. I mostly work in C# now and this 'feature' of C++ is something I do not get. You are right, that this should be bad code, but it work (at least in Visual Studio 2017).
I would also like to know, why this is not considered as error/incorrect code construction.

Why doesn't my inherited interface use my base class's override?

I have a problem with interfaces and multiple inheritance. I hope to design my program such that one update call processes a variety of objects, with each behavioral 'building block' tucked away in a single function.
For example, I'd like to move a creature from point A to B in one place, regardless of whether it must perform pre/post move actions. But, my multiple inheritance scheme fails (below, with the bug rem'd), making me think I'd need to duplicate code somewhere.
Clearly I don't understand this well enough! (but I'm working hard to learn it)
Q1. Why can't IPhysics::Move 'see' Creature::Move(), in the CreatureAirborne class?
Q2. Am I completely missing the proper usage of interfaces and/or multiple inheritance? If so, any guidance is appreciated!
#include <deque>
#include <memory>
class IGameObject
{
public:
virtual ~IGameObject() {}
virtual void Update() = 0;
};
class IPhysics
{
public:
virtual ~IPhysics() {}
virtual void Move() = 0;
};
class IPhysicsFlight : public IPhysics
{
public:
virtual ~IPhysicsFlight() {}
virtual void Land() = 0;
virtual void TakeOff() = 0;
};
class Creature : public IGameObject, IPhysics
{
protected:
virtual void Move() {}
public:
Creature() {}
virtual ~Creature() {}
virtual void Update() {}
};
class CreatureAirborne : public Creature, IPhysicsFlight
{
private:
virtual void Land() {}
virtual void TakeOff() {}
public:
CreatureAirborne() {}
virtual ~CreatureAirborne() {}
virtual void Update();
};
void CreatureAirborne::Update()
{
TakeOff();
Creature::Move();
Land();
}
int main()
{
std::deque<std::shared_ptr<Creature>> creatures;
std::shared_ptr<Creature> cow(new Creature);
creatures.push_back(cow);
// The butterfly fails to compile with 'cannot instantiate; void IPhysics::Move(void) is abstract'
// std::shared_ptr<CreatureAirborne> butterfly(new CreatureAirborne);
// creatures.push_back(butterfly);
for (auto i : creatures)
{
i->Update();
}
}
It's somewhat had to follow your hierarchy, but it looks correct evaluation on the compiler's part.
You don't have virtual inheritance anywhere, so CreatureAirborne will have duplicated base classes from some point. You will have two instances of IPhysics. Move, that is abstract from there is implemented on the Creature branch but remains abstract on IPhysicsFlight.
You can cure the situation by using virtual inheritance somewhere, or by implementing Move in descendant (say just calling the parent version where it exists).
I would look at things little differently
class CreatureAirborne : public IPhysicsFlight,Creature
While the code runs
new CreatureAirborne ()
The compiler will try to build IPhysicsFlight base class and Creature base class and the fact that IPhysics is a base class to both doesn't play any role rather than confusing.As far as compiler is concerned IPhysicsFlight is abstract and CreatureAirborne did not implement Move
The diamond issue will actually come into play when you do a
(new CreatureAirborne ())->Move()

Compile time check of whether a method defined as virtual

I'm trying to come up with a way of checking in the derived class whether a method of the base class is defines as 'virtual' . Basically I would like to have the following code:
class A {
virtual void vfoo() {}
void foo() {}
virtual ~A() {}
};
class B : public A {
virtual void vfoo() {
MAGIC_CHECK(m_pA->vfoo()); // succeed
// code
m_pA->vfoo();
// code
}
virtual void foo() {
MAGIC_CHECK(m_pA->foo()); // fail compilation because foo is not virtual!
// code
m_pA->foo();
// code
}
A * m_pA;
};
The question is, how do I implement this MAGIC_CHECK?
One solution for this could be using -Woverloaded-virtual compilation flag.
Can anyone suggest a solution that will not involve this flag?
Thanks!
In C++11 it's possible to add override at the end of the function declaration in the class and it will yield a warning if the function doesn't override anything:
class B : public A {
virtual void vfoo() override { //OK
}
virtual void foo() override { //error
}
};
In C++03 standard, it's not possible to check if a method is declared as virtual or not.
You may follow,
coding standards
peer review
possibly some static analysis tool

Restricting method call to another method

There probably is a fairly simple and straight-forward answer for this, but for some reason I can't see it.
I need to restrict calling methods from a class only to some methods implemented by derived classes of some interface.
Say I have
class A{
public:
static void foo();
};
class myInterface{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface{
public:
virtual void onlyCallFooFromHere()
{
A::foo(); //this should work
}
void otherFoo()
{
A::foo(); //i want to get a compilation error here
}
}
So I should be able to call A::foo only from the method onlyCallFooFromHere()
Is there a way to achieve this? I'm open to any suggestions, including changing the class design.
EDIT:
So... I feel there's a need to further explain the issue. I have a utility class which interacts with a database (mainly updates records) - class A.
In my interface (which represents a basic database objects) I have the virtual function updateRecord() from which I call methods from the db utility class. I want to enforce updating the database only in the updateRecord() function of all extending classes and nowhere else. I don't believe this to be a bad design choice, even if not possible. However, if indeed not possible, I would appreciate a different solution.
Change the class design - what you want is impossible.
I am unsure of what you are trying to achieve with so little details and I am unable to comment further.
[Disclaimer: this solution will stop Murphy, not Macchiavelli.]
How about:
class DatabaseQueryInterface {
public:
~virtual DatabseQueryInterface() = 0;
virtual Query compileQuery() const = 0; // or whatever
virtual ResultSet runQuery(const Query&) const = 0; // etc
};
class DatabaseUpdateInterface : public DatabaseQueryInterface {
public:
virtual Update compileUpdate() const = 0; // whatever
};
class DatabaseObject {
public:
virtual ~DatabaseObject() = 0;
protected:
virtual void queryRecord(const DatabaseQueryInterface& interface) = 0;
virtual void updateRecord(const DatabaseUpdateInterface& interface) = 0;
};
class SomeConcreteDatabaseObject : public DatabaseObject {
protected:
virtual void updateRecord(const DatabaseUpdateInterface& interface) {
// gets to use interface->compileUpdate()
}
virtual void queryRecord(const DatabaseQueryInterface& interface) {
// only gets query methods, no updates
}
};
So the basic idea is that your DatabaseObject base class squirrels away a private Query object and a private Update object and when it comes time to call the protected members of the subclass it hands off the Update interface to the updateRecord() method, and the Query interface to the queryRecord() method.
That way the natural thing for the subclasses is to use the object they are passed to talk to the database. Of course they can always resort to dirty tricks to store away a passed-in Update object and try to use it later from a query method, but frankly if they go to such lengths, they're on their own.
You could split your project into different TUs:
// A.h
class A
{
public:
static void foo();
};
// My.h
class myInterface
{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface
{
public:
virtual void onlyCallFooFromHere();
void otherFoo();
};
// My-with-A.cpp
#include "My.h"
#include "A.h"
void myImplementation::onlyCallFooFromHere() { /* use A */ }
// My-without-A.cpp
#include "My.h"
void myImplementation::otherFoo() { /* no A here */ }
You probably know this, but with inheritance, you can have public, protected, and private member access.
If a member is private in the base class, the derived cannot access it, while if that same member is protected, then the derived class can access it (while it still isn't public, so you're maintaining encapsulation).
There's no way to stop specific functions from being able to see whats available in their scope though (which is what you're asking), but you can design your base class so that the derived classes can only access specific elements of it.
This could be useful because class B could inherit from class A as protected (thus getting its protected members) while class C could inherit from the same class A as public (thus not getting access to its protected members). This will let you get some form of call availability difference at least -- between classes though, not between functions in the same class.
This could work.
class myInterface;
class A {
private:
friend class myInterface;
static void foo();
};
class myInterface {
public:
virtual void onlyCallFooFromHere() {callFoo();}
protected:
void callFoo() {A::foo();}
};
Though at this point I think I'd just make A::foo a static of myInterface. The concerns aren't really separate anymore.
class myInterface {
protected:
static void foo();
};
Is there a reason foo is in A?

How to solve a mesh inheritance problem in C++

I have the following set of classes that inherit from each other in a mesh way. In the top level, I have abstract classes. Both Abstract_Class_B and Abstract_Class_C inherit from Abstract_Class_A.
In the second level of inheritance, I have the exact implementations of those classes.
Impl_Class_A inherits from Abstract_Class_A.
Impl_Class_B inherits from both Abstract_Class_B and Impl_Class_A.
Impl_Class_C inherits from both Abstract_Class_C and Impl_Class_A.
When I compile the below code, the compiler compiles perfectly if I do not declare any class in the code. But when I start declaring pointer to the classes in the second level, the compiler gives the following error:
undefined reference to `VTT for ns3::Impl_Class_B'
undefined reference to `vtable for ns3::Impl_Class_B'
I used virtual to tackle the typical diamond problem in inheritance, but I am still not able to compile. It makes sense that the compiler gets confused because of this way of inheritance. But my system requires such a design for those classes. Any solution to fix this problem?
The code:
// Top Level (Level 1)
class Abstract_Class_A
{
};
class Abstract_Class_B: virtual public Abstract_Class_A
{
public:
uint8_t type;
};
class Abstract_Class_C: virtual public Abstract_Class_A
{
};
// Second Level (Level 2)
class Impl_Class_A : virtual public Abstract_Class_A
{
public:
double angle;
};
class Impl_Class_B: virtual public Abstract_Class_B, Impl_Class_A
{
};
class Impl_Class_C: virtual public Abstract_Class_C, Impl_Class_A
{
};
void test()
{
Impl_Class_B* test = new Impl_Class_B ();
}
The problem turned out to be related to other virtual functions inside the original classes that I had in my code. The code above works without any problem. During the development, I had encountered other problems so I post her a new code that solves all these problems with comments mentioned next to them:
// Top Level (Level 1)
class Abstract_Class_A
{
~Abstract_Class_A (); // To solve source type is not polymorphic” when trying to use dynamic_cast
};
class Abstract_Class_B: virtual public Abstract_Class_A
{
public:
uint8_t type;
};
class Abstract_Class_C: virtual public Abstract_Class_A
{
};
// Second Level (Level 2)
class Impl_Class_A : virtual public Abstract_Class_A
{
public:
double angle;
};
class Impl_Class_B: virtual public Abstract_Class_B, virtual public Impl_Class_A // Missing second virtual
{
};
class Impl_Class_C: virtual public Abstract_Class_C, virtual public Impl_Class_A // Missing second virtual
{
};
void test()
{
Impl_Class_B* test = new Impl_Class_B ();
}
Notes:
With this type of inheritance paradigm, you cannot use static_cast but rather dynamic_cast should be used. Check the following discussion.
When using dynamic_cast you should add a virtual destructor to the top class. Check the following discussion about it.