C++ Cannot convert child* to parent* by assignment - c++

Using the following two classes...
//pure virtual...
class Monkey
{
public:
virtual ~Monkey(){}
virtual void clearMonkeys() = 0;
virtual std::shared_ptr<std::vector<sf::Text>> getMonkeyListPtr() = 0;
virtual void addMonkey(String message,Vector2f position,float depthValue) = 0;
};
class NullMonkey : public Monkey
{
public:
NullMonkey () {/*Do Nothing*/}
virtual ~NullMonkey () {/*Do Nothing*/}
virtual void clearMonkeys(){/*Do Nothing*/};
virtual std::shared_ptr<std::vector<sf::Text>> getMonkeyListPtr()
{
//Do Nothing but...
//Return NULL shared pointer
std::shared_ptr<std::vector<sf::Text>> nullSharedPointer;
return nullSharedPointer;
//Of course I am ASSUMING I will check for NULL pointer...
}
virtual void addMonkey(String message,Vector2f position,float depthValue){/*Do Nothing*/};
};
...I have issues when casting.
Specifically I am using these classes as static members and have a situation where if one class is not available I use the Null class to fall back on to prevent app crash. It also adds the ability to hot-swap child classes for debug purposes.
Unfortunately the following...
class ServLoc
{
public:
ServLoc();
static void initialize()
{
theMonkey = &theNullMonkey; //Error here
}
//...
static Monkey* theMonkey;
static NullMonkey theNullMonkey;
};
...throws 'cannot convert NullMonkey* to Monkey* in assignment'.
I should also add add I have defined the static members in the .cpp file
NullMonkey ServLoc::theNullMonkey;
Monkey* ServLoc::theMonkey;
The funny thing is I have used similar classes in similiar situations before and did not get this error. I am at a loss. It is probably something simple but still...
In fact I implement a log class using this method. It means I can hot-swap various forms of logging (including the null logger to disable logging) and have access to the logger wherever by just using the ServLoc static members...
class Logger
{
public:
virtual ~Logger() {}
virtual void log(const logType type,const char *message) = 0;
//...
};
class NullLogger : public Logger
{
public:
virtual ~NullLogger() {/*Do Nothing*/};
NullLogger() {/*Do Nothing*/};
virtual void log(const logType type,const char *message) {/*Do Nothing*/};
//...
};
This when used in same way in ServLoc as shown above works fine!?
Any ideas?
Regards
Edit - Fixed spelling mistakes

I suspect (could you clarify?), that you are calling the static function initialize() from another statically initialized class? Since this would all be done at program startup (and C++ does not guarantee any static initialization order between files), initialize may be called before ServLoc::theNullMonkey; has been constructed?!

Related

Override virtual method with static method

Is there any specific reason why I cannot override virtual method from base class with static one?
Anyone knows why it would be bad idea?
Example:
#include <cstdio>
class Foo
{
public:
virtual void SomeMethod() = 0;
};
class Bar : public Foo
{
public:
static void SomeMethod() override
{
printf("SomeMethod");
}
};
void SomeFunctionWithFoo( Foo *p )
{
p->SomeMethod();
}
int main()
{
Bar o;
o.SomeMethod();
SomeFunctionWithFoo( &o );
Bar::SomeMethod();
o.StaticSomeMethod();
}
Instead I have to do this:
#include <cstdio>
class Foo
{
public:
virtual void SomeMethod() = 0;
};
class Bar : public Foo
{
public:
void SomeMethod() override
{
StaticSomeMethod();
}
static void StaticSomeMethod()
{
printf("SomeMethod");
}
};
void SomeFunctionWithFoo( Foo *p )
{
p->SomeMethod();
}
int main()
{
Bar o;
o.SomeMethod();
SomeFunctionWithFoo( &o );
Bar::StaticSomeMethod();
o.StaticSomeMethod();
}
I think as long as you don't need to access member variables, your function can be static, so that it can serve behaviour without object. In the same time such static function can serve behaviour when using interface. But maybe I am wrong and I am missing something?
With one method and two classes, it is not problem, but I have case of 10 such methods inside class, and many classes that inherit.
In real world scenario, such possibility would make my code simpler.
Summary: member functions have an invisible first parameter that your static method doesn't have.
Details: Member functions (effectively) are effectively all static methods that have an "invisible" first parameter, which is the Bar* this parameter, which tells the method which instance of the class to use. So the signature of virtual void SomeMethod() is, under the covers, actually static void SomeMethod(Foo*), but static StaticSomeMethod() doesn't have the same number of parameters.
C++ is mostly able to pretend this parameter doesn't exist, but overrides are one case where it pops up. You also see it occur when trying to bind a member function to a std::function, where you have to explicitly pass the this as the first pointer.

Diamond inheritence - Inheriting from an abstract class and also a concrete class than implements a shared based class

Please Consider:
IReferenceCounting is a pure abstract class, with methods AddRef and RemoveRef
virtual void AddRef() noexcept = 0;
virtual void RemoveRef() noexcept = 0;
I did not build this class, nor can I change it.
Now I have another class, which I did build, called ISoundComponent that inherits from IReferenceCounting. Class ISoundComponent is also abstract (for a start it doesn't contain a definition for AddRef or Release).
As every component that inherits from IReferenceCounted will need to implement AddRef and RemoveRef, there exists ReferenceCountedImpl, which inherits from IReferenceCounted. I did not build this class and I cannot change it.
Finally, I have another class I did build, say SoundDiagnostics, which inherits from ISoundComponent and ReferenceCountedImpl
Many have you have already seen it - I have a diamond inheritance problem. By not providing my own AddRef and RemoveRef, and instead using ReferenceCountedImpl, means I would need ISoundComponent and ReferenceCountedImpl to inherit virtually from IReferenceCounted... correct?
Unfortunately I cannot edit ReferenceCountedImpl only ISoundComponent . This is because IReferenceCounting and ISoundComponent live across many projects in our codebase but ReferenceCountedImpl lives inside only a single project (the same project SoundDiagnostics lives). This makes sense, as a project can decide on how it wants to implement the IReferenceCounting, and we should be able to reuse it inside different classes in that project.
Unfortunately, as I cannot go and edit ReferenceCountedImpl, I cannot build this, due to the diamond inheritance problem (SoundDiagnostics won't know whether to call ReferenceCountedImpl::AddRef or ISoundComponent ::AddRef).
I feel like I'm barking up the wrong tree, missing something obvious, getting caught up in the details of virtual inheritance and/or and my design is messed up. The codebase organization should be agnostic to this problem. Can anyone give me some guidance on how this should be architected? I don't think ReferenceCountedImpl inheriting virtually from IReferenceCounted is the solution - e.g. there are performance reasons to consider when doing this.
Interested to learn how to tackle this.
EDIT:
// available across all projects in code base
class IReferenceCounted
{
virtual void AddRef() = 0;
virtual void RemoveRef() = 0;
};
// available across a few select projects in the codebase (ones that wish to use some kind of sound component)
class ISoundComponent : public virtual IReferenceCounted
{
virtual void Play() const = 0;
};
// available within one specific project, SoundDiagnostics. I cannot modify this
class ReferenceCountedImpl : public IReferenceCounted
{
void AddRef() override
{
m_refcount++;
}
void RemoveRef() override
{
if (--m_refcount == 0)
{
delete this;
}
}
int m_refcount = 0;
};
// available within one specific project, SoundDiagnostics.
class SoundDiagnostics : public ISoundComponent, public ReferenceCountedImpl
{
void Play() const override
{
return;
}
void RunDiagnostics()
{
}
};
// function within my SoundDiagnostics project
int main()
{
SoundDiagnostics soundDiagnostics;
return 0;
}
Trying to compile this will produce
object of abstract class type "SoundDiagnostics" is not allowed:
pure virtual function "IReferenceCounted::AddRef" has no overrider
pure virtual function "IReferenceCounted::RemoveRef" has no overrider
If ReferenceCountedImpl inherits virtually from IReferenceCounted then this code compiles successfully.
I tried to turn your description into code. It works.
class IReferenceCounting {
public:
virtual void AddRef() const noexcept = 0;
virtual void RemoveRef() const noexcept = 0;
};
class IComponentPublicHeader :public virtual IReferenceCounting {};
class ReferenceCountedImpl :public virtual IReferenceCounting {
public:
void AddRef() const noexcept override {};
void RemoveRef() const noexcept override {};
};
class MyAmazingClass : IComponentPublicHeader, ReferenceCountedImpl {
MyAmazingClass() {
AddRef();// ReferenceCountedImpl::AddRef
}
};
Update:I read your code snippet.If AddRef and RemoveRef is public,You can try to implement your class like this.
class SoundDiagnostics : public ISoundComponent, public ReferenceCountedImpl
{
void Play() const override
{
return;
}
void AddRef() override
{
ReferenceCountedImpl::AddRef();
}
void RemoveRef() override
{
ReferenceCountedImpl::RemoveRef();
}
void RunDiagnostics()
{
}
};
If AddRef and RemoveRef is private,let ISoundComponent not inherit the IReferenceCounted.
class ISoundComponent
{
virtual void Play() const = 0;
};

CRTP causing segfault

I have a pure virtual class Interface:
class Interface {
public:
virtual ~Interface() noexcept;
virtual void open()=0;
virtual void close()=0;
protected:
explicit Interface(const string params);
string params_;
}
I then have an abstract class where I implement my business logic:
template<typename T>
class AbstractInterface : public Interface {
public:
void open() override;
void close() override;
void read_is_complete(const vector<byte_array>);
protected:
explicit AbstractInterface(const string params);
virtual ~AbstractInterface() noexcept;
}
Then there is the implementation for the interface that uses CRTP for polymorphism:
class SPInterface : public AbstractInterface<SPInterface> {
public:
explicit SPInterface(const string params);
virtual ~SPInterface() noexcept;
void open();
void close();
void read_is_complete(const vector<byte_array> data);
}
I have a unit test where I create an instance of SPInterface:
unique_ptr<Interface> intf;
intf.reset(new SPInterface("aaa"));
Letting this get out of scope calls the destructor AbstractInterface which in turn calls the close method on AbstractInterface and then it segfaults on this:
template<typename T>
void AbstractInterface<T>::close() {
static_cast<T *>(this)->close();
params_ = "";
}
Which is confusing as I already created an instance of the class. lldb seems to confirm:
AbstractInterface<SPInterface>::close(this=<unavailable>)
Letting this get out of scope calls the destructor AbstractInterface which in turn calls the close method on AbstractInterface and then it segfaults on this:
template<typename T>
void AbstractInterface<T>::close() {
static_cast<T *>(this)->close();
params_ = "";
}
It seems that you are trying to invoke a method of a derived class from within the destructor of a base class.
This is not safe at all and a segfault is the way the executable has to tell you that it doesn't approve that. :-)
Even though CRTP allows you to invoke a member function that belongs to the derived class on a (let me say) living object, it doesn't change the way an object is destructed.
Do not forget that bases and members are destroyed in the reverse order of the completion of their constructor.

how to pass method of child as parameter to function in parent

In the following exceedingly abbreviated classes I would like to define in the base a method (ProcessLines) that would iterate over a set of database records, passing each record as a parameter to a function that is only defined in the child class. Obviously the Base is a virtual class that will never be instantiated on its own.
Class Base {
public:
typedef ProcLineFunc( Long *Line );
void ProcessLines( ProcLineFunc pf);
}
Class Child{
void DoWork( Long *Line) { //do something}
}
I'm not sure how to implement this. If I redeclare ProcessLines in the child and just call the parent method, I get the same error message as if I call ProcessLines in the code that creates the child.
Child c(//something);
c.ProcessLines(c.DoWork);
Gives me a compiler message:
[BCC32 Error] main.cpp(67): E2034 Cannot convert 'bool (* (_closure )(long *))(long )' >to 'int ()(long *)'
Full parser context
main.cpp(56): class Add2Chan
main.cpp(78): decision to instantiate: bool Add2Chan::ProcessByLines()
--- Resetting parser context for instantiation...
main.cpp(67): parsing: bool Add2Chan::ProcessByLines()
I'm fairly new to c++ and the E2034 error message scares the daylights out of me.
Please help. I used a typedef so that I can, in my child classes call ProcessLines multiple times, passing in different functions as I go.
Normally you would do this sort of thing with a protected, pure virtual function:
class Base {
public:
ProcessLines() {
//Logic to process lines here, obviously psuedo-code
while(moreLines) {
ProcessLine(line);
}
}
protected:
virtual void ProcessLine(const Line& line) = 0;
}
class Child : public Base {
protected:
void ProcessLine(const Line& line) { //Logic to process the line for this type }
};
class DifferentChild : public Base {
protected:
void ProcessLine(const Line& line) { //Logic to process the line for DifferentChild }
};
I think this is the kind of thing you're looking for. It appears to me like you're trying to implement polymorphism in an odd way, but this is the normal way to do it in C++.
Instead of using pointers to functions, use pointers to objects. Accept the limitation that your function is going to be called DoWork and nothing else, and there can only be one such function in each class. This is not a bad limitation. Declare the (pure virtual) function in a class (which is called an interface), and derive classes from it (they are said to implement an interface).
struct DoingWork
{
virtual void DoWork(long *Line) = 0; // does some work on a list
};
struct DoingGreatWork: DoingWork
{
virtual void DoWork(long *Line) {printf("Great work\n");}
};
struct DoingSlightWork: DoingWork
{
virtual void DoWork(long *Line) {printf("Slight work\n");}
};
Using this example:
class Base {
public:
void ProcessLines(DoingWork& object) {
//Logic to process lines here
while(moreLines) {
object.DoWork(line);
}
}
};
class Whatever // no need to derive from Base
{
void DoStuff()
{
Base object;
object.ProcessLines(DoingGreatWork());
object.ProcessLines(DoingSlightWork());
}
}
If the working objects have to have access to the calling object, initialize them like this:
class Whatever // no need to derive from Base
{
struct DoingElaborateWork: DoingWork
{
Whatever& caller;
DoingElaborateWork(Whatever& caller): caller(caller) {}
virtual void DoWork(long *Line)
{
printf("Doing work requested by %s\n", caller.name());
}
};
void DoStuff()
{
Base object;
object.ProcessLines(DoingElaborateWork(*this));
}
const char* name() {return "Whatever";}
}
P.S. They say that "in C++03 functions are second-class citizens" because you cannot do with functions what you can do with objects (like this solution i provide). I heard that in C++11 functions are much improved, but i am not sure about the details.
Since you are doing this in C++Builder, you can utilize its __closure extension to do exactly what you asked for (some portions of the VCL do exactly this for their own callbacks):
class Base
{
public:
virtual ~Base() {}
typedef void (__closure *ProcLineFunc)( Long *Line );
void ProcessLines( ProcLineFunc pf);
};
class Child : public Base
{
public:
void DoWork( Long *Line) { //do something}
};
Child c(...);
c.ProcessLines(c.DoWork);

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?