I have code similar to the following:
template<class BASE_TYPE = COdbcQuery>
class CRemoteQuery : public BASE_TYPE
{
CRemoteDatabase m_Db;
public:
CRemoteQuery()
: BASE_TYPE(&m_Db)
{
}
~CRemoteQuery()
{
}
};
My problem is that m_Db.Open() must be called before passing m_Db to the base constructor.
If I call a method as an argument to the base constructor that calls Open(), it fails because m_Db has not yet been initialized.
I tried creating a virtual method in the base class, which would be called during initialization and this class could override, but template classes cannot override virtual methods.
Restructuring my base classes so that m_Db doesn't need to be opened first raises a lot of difficult issues. Is there no way to do this?
This sequence of events can be easily implemented by making a small design change:
class CRemoteDB {
protected:
CRemoteDatabase m_Db;
CRemoteDB()
{
m_Db.open();
}
};
template<class BASE_TYPE = COdbcQuery>
class CRemoteQuery : private CRemoteDB, public BASE_TYPE
{
public:
CRemoteQuery()
: BASE_TYPE(&m_Db)
{
}
~CRemoteQuery()
{
}
};
Parent classes always get constructed in declaration order. The CRemoteDB parent class gets constructed first, and CRemoteDatabase::open() gets called in the parent class's constructor.
Then BASE_TYPE gets constructed, and gets a pointer to the opened m_Db.
CRemoteQuery can access m_Db from its parent class no differently than it would be if it was its own class member.
but template classes cannot override virtual methods.
P.S. Whoever told you that was wrong. Template classes can certainly override virtual methods. I've got a massive hierarchy of templates here, all overriding virtual methods of their parent classes, left and right.
Related
I'm reading this code from OpenVPN3:
class OptionList : public std::vector<Option>, public RCCopyable<thread_unsafe_refcount>
{
void clear()
{
std::vector<Option>::clear();
map_.clear();
}
};
How is it possible that the class method clear calls std::vector<Option>::clear()? std::vector's clear is a method, not static function. How can it be called without an instance?
OptionList derives from std::vector<Option>:
https://github.com/OpenVPN/openvpn3/blob/f1a32af29cd41b62212829d6713198207ed5315c/openvpn/common/options.hpp#L385
class OptionList : public std::vector<Option>, public RCCopyable<thread_unsafe_refcount>
So it's not calling clear() without an instance; it's calling the clear() function on the parent class. Without indicating std::vector<Option>::, it would call the clear() function on the derived class, leading to infinite recursion.
Note that clear() is not declared virtual in std::vector, and OptionList inherits publicly from std::vector<Option>. This is questionable design, because it goes against the Liskov Substitution Principle: you can't use an OptionList where std::vector<Option> is expected, because the wrong clear() will be called, probably violating the expectations of the OptionList class.
There is no static method involved here and no call "without object". The class you are looking at is:
class OptionList : public std::vector<Option>, public RCCopyable<thread_unsafe_refcount>
So the line
std::vector<Option>::clear();
Calls the member function clear of the base class. This is similar to
struct base {
void some_method() {};
};
struct dervied : base {
void some_method() { // note: not virtual, hides base method
base::some_method(); // calls method from base
};
};
There is an instance, it's *this.
clear is a member of OptionList, which inherits std::vector<Option>. The call is qualified because otherwise it would be infinitely recursive
This is a question about designing classes in C++.
My base class have virtual final method with parameters, the name of it is basically "update". In a child class, I wanted to use a higher level way to update the object, so I made a method called "update" too (for convenience), but this one have no parameter. And Clang warns me the method is hiding a base class method. In my point of view, I'm not totally agree with this, because the signature is different, it should just complete the overloading.
Is there a good reason to not do that ?
The warning is telling you that the function in the derived class makes it more difficult to call the original base class function on an object of the derived type:
class Base {
public:
virtual void update(int param) final;
};
class Derived : public Base {
public:
void update();
};
void f(Derived& obj) {
obj.update(2); // Error!
// Name lookup for update finds only Derived::update,
// which takes no arguments
}
To "unhide" the base class function, so that the derived class acts as though it has both overloads, use a using directive:
class Derived : public Base {
public:
void update();
using Base::update;
};
Let's say I have the following code:
class BaseMember
{
};
class DerivedMember : public BaseMember
{
};
class Base
{
private:
BaseMember* mpMember;
protected:
virtual BaseMember* initializeMember(void)
{
return new BaseMember[1];
}
virtual void cleanupMember(BaseMember* pMember)
{
delete[] pMember;
}
public:
Base(void)
: mpMember(NULL)
{
}
virtual ~Base(void)
{
cleanupMember(mpMember);
}
BaseMember* getMember(void)
{
if(!mpMember)
mpMember = initializeMember();
return mpMember;
}
};
class Derived : public Base
{
protected:
virtual BaseMember* initializeMember(void)
{
return new DerivedMember;
}
virtual void cleanupMember(BaseMember* pMember)
{
delete pMember;
}
};
Base and BaseMember are parts of an API and may be subclassed by the user of that API, like it is done via Derived and DerivedMember in the example code.
Base initializes mpBaseMember by a call to it's virtual factory function initializeMember(), so that the derived class can override the factory function to return a DerivedMember instance instead of a BaseMember instance.
However, when calling a virtual function from within a base class constructor, the base implementation and not the derived class override gets called.
Therefor I am waiting with the initialization of mpMember until it gets accessed for the first time (which of course implies, that the base class and any derived class, that may could get derived further itself, are not allowed to access that member from inside the constructor).
Now the problem is: Calling a virtual member function from within the base base destructor will result in a call of the base class implementation of that function, not of the derived class override.
That means that I can't simply call cleanupMember() from within the base class destructor, as that would call it's base class implementation, which may not be able to correctly cleanup the stuff, that the derived implementation of initializeMember() has initialized.
For example the base class and the derived class could use incompatible allocators that may result in undefined behavior when getting mixed (like in the example code - the derived class allocates the member via new, but the base class uses delete[] to deallocate it).
So my question is, how can I solve this problem?
What I came up with is:
a) the user of the API has to explicitly call some cleanup function before the Derived instance gets destructed. That can likely be forgotten.
b) the destructor of the (most) derived class has to call a cleanup function to cleanup stuff which initialization has been triggered by the base class. That feels ugly and not well designed as ownership responsibilities are mixed up: base class triggers allocation, but derived class has to trigger deallocation, which is very counter-intuitive and can't be known by the author of the derived class unless he reads the API documentation thoroughly enough to find that information.
I would really like to do this in a more fail-proof way than relying on the users memory or his reliability to thoroughly read the docs.
Are there any alternative approaches?
Note: As the derived classes may not exist at compile time of the base classes, static polymorphism isn't an option here.
What about a modification of the factory pattern that would include the cleanup method? Meaning, add a attribute like memberFactory, an instance of a class providing creation, cleanup, as well as access to the members. The virtual initialization method would provide and initialize the right factory, the destructor ~Base would call the cleanup method of the factory and destruct it.
(Well, this is quite far from the factory pattern... Perhaps it is known under another name?)
If you really want to do this sort of thing you can do it like this:
class Base {
BaseMember* mpMember;
protected:
Base(BaseMember *m) : mpMember(m) {}
virtual void doCleanupMember(BaseMember *m) { delete [] m; }
void cleanupMember() {
// This gets called by every destructor and we only want
// the first call to do anything. Hopefully this all gets inlined.
if (mpMember) {
doCleanupMember(pmMember);
mpMember = nullptr;
}
}
public:
Base() : mpMember(new BaseMember[1]) { }
virtual ~Base(void) { cleanupMember(); }
};
class Derived : public Base {
virtual void doCleanupMember(BaseMember *m) override { delete m; }
public:
Derived() : Base(new DerivedMember) {}
~Derived() { cleanupMember(); }
};
However there are reasons this is a bad idea.
First is that the member should be owned an exclusively managed by Base. Trying to divide up responsibility for Base's member into the derived classes is complicated and just asking for trouble.
Secondly the ways you're initializing mpMember mean that the member has a different interface depending on who initialized it. Part of the problem you've already run into is that the information on who initialized the member has been destroyed by the type you get to ~Base(). Again, trying to have different interfaces for the same variable is just asking for trouble.
We can at least fix the first problem by using something like shared_ptr which lets up specify a deleter:
class Base {
std::shared_ptr<BaseMember> mpMember;
public:
Base(std::shared_ptr<BaseMember> m) : mpMember(m) { }
Base() : mpMember(std::make_shared<BaseMember>()) { }
virtual ~Base() {}
};
class Derived : virtual public Base {
public:
Derived()
: Base(std::shared_ptr<BaseMember>(new DerivedMember[1],
[](BaseMember *m){delete [] m;} ) {}
};
This only hides the difference in the destruction part of the member's interface. If you had an array of more elements the different users of the member would still have to be able to figure out if mpMember[2] is legal or not.
First of all, you must use RAII idiom when developing in C++. You must free all your resources in destructor, of course if you don't wish to fight with memory leaks.
You can create some cleanupMember() function, but then you should check your resources in destructor and free them if they are not deleted (as cleanupMember can be never called, for example because of an exception). So add destructor to your derived class:
virtual ~Derived()
{
Derived::cleanupMember(mpMember);
}
and manage the member pointer in the class itself.
I also recommend you to use smart pointers here.
Never never never call virtual methods in constructor/destructor because it makes strange results (compiler makes dark and weird things you can't see).
Destructor calling order is child and then parent
You can do like this (but there is probalby a better way) :
private:
// private destructor for prevent of manual "delete"
~Base() {}
public:
// call this instead use a manual "delete"
virtual void deleteMe()
{
cleanupMember(mpMember);
delete this; // commit suicide
}
More infos about suicide :
https://stackoverflow.com/a/3150965/1529139 and http://www.parashift.com/c++-faq-lite/delete-this.html
PS : Why destructor is virtual ?
Let mpMember be protected and let it be initialized in derived class constructor and deallocated in derived destructor.
Inspired by the ideas from https://stackoverflow.com/a/19033431/404734 I have come up with a working solution :-)
class BaseMember
{
};
class DerivedMember : public BaseMember
{
};
class BaseMemberFactory
{
public:
virtual ~BaseMemberFactory(void);
virtual BaseMember* createMember(void)
{
return new BaseMember[1];
}
virtual void destroyMember(BaseMember* pMember)
{
delete[] pMember;
}
};
class DerivedMemberFactory : public BaseMemberFactory
{
virtual BaseMember* createMember(void)
{
return new DerivedMember;
}
virtual void destroyMember(BaseMember* pMember)
{
delete pMember;
}
};
class Base
{
private:
BaseMemberFactory* mpMemberFactory;
BaseMember* mpMember;
protected:
virtual BaseMemberFactory* getMemberFactory(void)
{
static BaseMemberFactory fac;
return &fac;
}
public:
Base(void)
: mpMember(NULL)
{
}
virtual ~Base(void)
{
mpMemberFactory->destroyMember(mpMember);
}
BaseMember* getMember(void)
{
if(!mpMember)
{
mpMemberFactory = getMemberFactory();
mpMember = mpMemberFactory->createMember();
}
return mpMember;
}
};
class Derived : public Base
{
protected:
virtual BaseMemberFactory* getMemberFactory(void)
{
static DerivedMemberFactory fac;
return &fac;
}
};
Let's say I have pure abstract class IHandler and my class that derives from it:
class IHandler
{
public:
virtual int process_input(char input) = 0;
};
class MyEngine : protected IHandler
{
public:
virtual int process_input(char input) { /* implementation */ }
};
I want to inherit that class in my MyEngine so that I can pass MyEngine* to anyone expecting IHandler* and for them to be able to use process_input.
However I don't want to allow access through MyEngine* as I don't want to expose implementation details.
MyEngine* ptr = new MyEngine();
ptr->process_input('a'); //NOT POSSIBLE
static_cast<IHandler*>(ptr)->process_input('a'); //OK
IHandler* ptr2 = ptr; //OK
ptr2->process_input('a'); //OK
Can this be done via protected inheritance and implicit casting?
I only managed to get:
conversion from 'MyEngine *' to 'IHandler *' exists, but is inaccessible
Since I come from C# background, this is basically explicit interface implementation in C#.
Is this a valid approach in C++?
Additional:
To give a better idea why I want to do this, consider following:
Class TcpConnection implements communication over TCP, and in its constructor expects pointer to interface ITcpEventHandler.
When TcpConnection gets some data on a socket, it passes that data to its ITcpEventHandler using ITcpEventHandler::incomingData, or when it polls for outgoing data it uses ITcpEventHandler::getOutgoingData.
My class HttpClient uses TcpConnection (aggregation) and passes itself to TcpConnection constructor, and does processing in those interface methods.
So TcpConnection has to implement those methods, but I don't want users using HttpClient to have direct access to ITcpEventHandler methods (incomingData, getOutgoingData). They should not be able to call incomingData or getOutgoingData directly.
Hope this clarifies my use case.
Deriving with protected makes the members of the base class inaccessible through a pointer to the derived class, and disallows the implicit conversion.
It seems to me that what you want is not to forbid access through the base class (interface), but rather through the derived class (concrete implementation):
class IHandler
{
public:
virtual int process_input(char input) = 0; //pure virtual
virtual std::string name() { return "IHandler"; } //simple implementation
};
class MyEngine : public IHandler
// ^^^^^^
{
protected: // <== Make the functions inaccessible from a pointer
// or reference to `MyEngine`.
virtual int process_input(char input) { return 0; } //override pure virtual
using IHandler::name; //use IHandler version
};
Here, in the derived class you basically override the visibility of the process_input function, so that clients can only call them through a pointer or reference to the base class.
This way you will make this impossible:
MyEngine* ptr = new MyEngine();
ptr->process_input('a'); // ERROR!
std::cout << ptr->name(); // ERROR!
But this will be possible:
IHandler* ptr = new MyEngine();
ptr->process_input('a'); // OK
std::cout << ptr->name(); // OK
In C++ protected and private inheritance serve the use of inheritance of the implementation. This is, you define a class with methods, a template class for example and when you want to use its functionality but not its interface, you inherit protected or private. So actually your base class would need to define the methods you want to use in the sub-class.
Here is a link on this topic. It really is difficult, I agree.
It's slightly hard to understand the real goal you hope to achieve here, because whether you call the method on the parent or child, as long as it's virtual the same one will be called.
That said you have a couple options.
You could make it so the user can't get a pointer (or object) of the child type by forcing a create call that returns an interface. Then you don't have to worry about artificial restrictions, they just can't get a child at all:
class Concrete : public Interface
{
public:
static Interface* create() { return new Concrete; }
private:
Concrete() { }
};
You could override the interface as protected as shown in a different answer.
You could utilize the non-virtual interface pattern to make the entire accessible public interface defined in the parent. Then it doesn't matter what object they have, they always get the public API from the interface class:
class Interface
{
public:
void foo() { foo_impl(); }
private:
virtual void foo_impl() = 0;
};
class Concrete
{
private:
virtual void foo_impl() { }
};
One very common mistake with class hierarchies is to specify a method in a base class as being virtual, in order for all overrides in the inheritance chain to do some work, and forgetting to propagate the call on to base implementations.
Example scenario
class Container
{
public:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Nothing to do here
}
};
class SpecializedContainer : public Container
{
protected:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Set some property of pObject and pass on.
Container::PrepareForInsertion(pObject);
}
};
class MoreSpecializedContainer : public SpecializedContainer
{
protected:
virtual void PrepareForInsertion(ObjectToInsert* pObject)
{
// Oops, forgot to propagate!
}
};
My question is: is there a good way/pattern to ensure that the base implementation always gets called at the end of the call chain?
I know of two methods to do this.
Method 1
You can use a member variable as a flag, set it to the correct value in the base implementation of the virtual method, and check its value after the call. This requires to use a public non-virtual method as interface for the clients, and making the virtual method protected (which is actually a good thing to do), but it requires the use of a member variable specifically for this purpose (which needs to be mutable if the virtual method must be const).
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
m_callChainCorrect = false;
PrepareForInsertionImpl(pObject);
assert(m_callChainCorrect);
}
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
m_callChainCorrect = true;
}
private:
bool m_callChainCorrect;
};
class SpecializedContainer : public Container
{
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
// Do something and pass on
Container::PrepareForInsertionImpl(pObject);
}
};
Method 2
The other way to do it is to replace the member variable with an opaque "cookie" parameter and do the same thing:
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
bool callChainCorrect = false;
PrepareForInsertionImpl(pObject, &callChainCorrect);
assert(callChainCorrect);
}
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject, void* pCookie)
{
*reinrepret_cast<bool*>(pCookie) = true;
}
};
class SpecializedContainer : public Container
{
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject, void* pCookie)
{
// Do something and pass on
Container::PrepareForInsertionImpl(pObject, pCookie);
}
};
This approach is inferior to the first one in my opinion, but it does avoid the use of a dedicated member variable.
What other possibilities are there?
You've come up with some clever ways to do this, at (as you acknowledge) the cost of bloating the class and adding code that addresses not the object's responsibilities but programmer deficiences.
The real answer is not to do this at runtime. This is a programmer error, not a runtime error.
Do it at compile time: use a language construct if the language supports it, or use a Pattern the enforces it (e.g,, Template Method), or make your compilation dependent on tests passing, and set up tests to enforce it.
Or, if failing to propagate causes the derived class to fail, let it fail, with an exception message that informs the author of the derived class that he failed to use the base class correctly.
What you are looking for is simply the Non-Virtual Interface pattern.
It's similar to what you are doing here, but the base class implementation is guaranteed to be called because it's the only implementation that can be called. It eliminates the clutter that your examples above require. And the call through the base class is automatic, so derived versions don't need to make an explicit call.
Google "Non-Virtual Interface" for details.
Edit: After looking up "Template Method Pattern", I see that it's another name for Non-Virtual Interface. I've never heard it referred to by the name before (I'm not exactly a card-carrying member of the GoF fan club). Personally, I prefer the name Non-Virtual Interface because the name itself actually describes what the pattern is.
Edit Again: Here's the NVI way of doing this:
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
PrepareForInsertionImpl(pObject);
// If you put some base class implementation code here, then you get
// the same effect you'd get if the derived class called the base class
// implementation when it's finished.
//
// You can also add implementation code in this function before the call
// to PrepareForInsertionImpl, if you want.
}
private:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject) = 0;
};
class SpecializedContainer : public Container
{
private:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
// Do something and return to the base class implementation.
}
};
When there's only one level of inheritance you can use the template method pattern where the public interface is non-virtual and calls a virtual implementation function. Then the base's logic goes in the public function which is assured to be called.
If you have more than one level of inheritance and want each class to call its base class then you can still use the template method pattern, but with a twist, make the return value of the virtual function only constructable by base so derived will be forced to call the base implementation in order to return a value (enforced at compile time).
This doesn't enforce that each class calls its direct base class, it may skip a level (I can't think of a good way to enforce that) but it does force the programmer to make a conscious decision, in other words it works against inattentiveness not malice.
class base {
protected:
class remember_to_call_base {
friend base;
remember_to_call_base() {}
};
virtual remember_to_call_base do_foo() {
/* do common stuff */
return remember_to_call_base();
}
remember_to_call_base base_impl_not_needed() {
// allow opting out from calling base::do_foo (optional)
return remember_to_call_base();
}
public:
void foo() {
do_foo();
}
};
class derived : public base {
remember_to_call_base do_foo() {
/* do specific stuff */
return base::do_foo();
}
};
If you need the public (non virtual) function to return a value the inner virtual one should return std::pair<return-type, remember_to_call_base>.
Things to note:
remember_to_call_base has an explicit constructor declared private so only its friend (in this case base) can create a new instance of this class.
remember_to_call_base doesn't have an explicitly defined copy constructor so the compiler will create one with public accessibility which allows returning it by value from the base implementation.
remember_to_call_base is declared in the protected section of base, if it was in the private section derived won't be able to reference it at all.
A completely different approach would be to register functors. Derived classes would register some function (or member function) with the base class while in the derived class constructor. When the actual function is called by the client it is a base class function which then iterates through the registered functions. This scales to many levels of inheritance, each derived class only has to be concerned with its own function.
Look at the template method pattern. (The basic idea is that you don't have to call the base class method anymore.)
One way out is to not use virtual methods at all, but instead to allow the user to register callbacks, and call those before doing the work of prepareForInsertion. This way it becomes impossible to make that mistake since it is the base class that makes sure that both the callbacks and the normal processing happen. You can end up with a lot of callbacks if you want this behaviour for a lot of functions. If you really do use that pattern so much, you might want to look into tools like AspectJ (or whatever the C# equivalent is) that can automate this sort of thing.
If you found out you can hide virtual function and make interface non-virtual, try instead of checking if other users did call your function just call it by yourself. If your base code should be called at the end, it would look like this:
class Container
{
public:
void PrepareForInsertion(ObjectToInsert* pObject)
{
PrepareForInsertionImpl(pObject);
doBasePreparing(pObject);
}
protected:
virtual void PrepareForInsertionImpl(ObjectToInsert* pObject)
{
// nothing to do
}
private:
void doBasePreparing(ObjectToInsert* pObject)
{
// put here your code from Container::PrepareForInsertionImpl
}
};