I have an object hierarchy and need to be able to clone objects from the base class. I've followed the typical CRTP pattern, except that I also want to be able to return the child class if copy is called on a child directly. To do that, I've followed the suggestion here: https://stackoverflow.com/a/30252692/1180785
It seems to work fine, but Clang warns me that I have a potential memory leak. I've reduced the code down to this MCVE:
template <typename T>
class CRTP {
protected:
virtual CRTP<T> *internal_copy(void) const {
return new T(static_cast<const T&>(*this));
}
public:
T *copy(void) const {
return static_cast<T*>(internal_copy());
}
virtual ~CRTP(void) = default;
};
class Impl : public CRTP<Impl> {
};
int main(void) {
Impl a;
Impl *b = a.copy();
delete b;
}
As far as I can tell, there's no possible memory leak there, but running Clang through XCode shows this:
Is there a memory leak here? If not, what's causing the false positive and how can I work around it? (I'd rather not turn off static analysis)
I have found a workaround which makes the analyser happy while still allowing the use of this pattern. Simply reverse the link between copy and internal_copy:
template <typename T>
class CRTP : public Base {
protected:
virtual CRTP<T> *internal_copy(void) const {
return copy();
}
public:
T *copy(void) const {
return new T(static_cast<const T&>(*this));
}
};
This still works in the context of the original suggestion here, because when resolving copy inside CRTP, it will prefer CRTP's override (even though it isn't a virtual method), so there is no infinite loop.
As for why the analyser is happy with this order but unhappy with the original order, I have no idea.
I think the analyzer is getting confused by the static_cast in your copy method. If you simply change it to dynamic_cast, it ceases to flag the line as a memory leak. This leads me to believe that it thinks you are possibly casting a base type instance (CRTP<T>) to its derived type (T), which would of course be invalid when dereferenced. You are obviously not doing this, so this may be a bug in the leak detector, or it may be onto something more subtle than what I'm thinking about right now. It may not be an error now, but if Impl becomes a more complicated type (e.g., one with multiple inheritance), it may become an issue (as will your static_cast in the copy-CTOR invocation).
This implementation (with fewer casts) had zero leaks for me as well:
template <typename T>
class CRTP {
protected:
virtual T *internal_copy() const {
return new T(static_cast<const T&>(*this));
}
public:
T *copy() const {
return internal_copy();
}
virtual ~CRTP() = default;
};
Related
Consider the following abstract class, which will be the interface for a class that writes the information carried by some object to standard output.
class FileBuilder
{
public:
virtual void build(const Object& object) = 0;
virtual ~FileBuilder() = default;
};
At this point I will note that Object is also an abstract class with derived class SpecialObject. Now I am going to implement SpecialFileBuilder : FileBuilder, as follows.
class SpecialFileBuilder : public FileBuilder
{
public:
void build(const SpecialObject& specialObject);
};
...
void SpecialFileBuilder::build(const SpecialObject& specialObject)
{
// Do some stuff
}
I don't fully understand why this should not be possible. SpecialFileBuilder respects the interface FileBuilder, and everywhere which expects a FileBuilder can instead be given a SpecialFileBuilder. I appreciate your help in advance.
Of course, this would work if I changed things to the following.
void SpecialFileBuilder::build(const Object& object)
However, in my implementation of SpecialFileBuilder::build() I need to use the fact that the argument is a SpecialObject, not just an Object.
How should I instead approach this design?
TL;DR no, this does not make any sense.
Full version below.
I don't fully understand why this should not be possible.
virtual void build(const Object& object) = 0;
This declaration is a promise. It promises that build can accept any Object as an argument. Such promises are legally binding for derived classes, i.e. they must implement the promise as stated by the base class. Note the declaration does not promise that build can accept some objects and not others.
FileBuilder* builder = GetBuilder(); // we don't know what kind of builder it is
SpecialObject some;
builder->build(some); // must work
OtherSpecialObject some;
builder->build(other); // must work too
UnrelatedObject whatever;
builder->build(whatever); // must work as well
Now looking at the other declaration
void build(const SpecialObject& specialObject);
It reneges on the promise. The original promise is strong. Give me any object, I can deal with it. The new promise is weak. Oh, I am a special little builder, I can only cope with special little objects!
Sorry bud, you cannot override a strong promise with a weaker one. If you were allowed to, how would we be able to trust any promise?
Now if your design doesn't fit in this outline, i.e. you always know what kind of builder you get, and you don't want to promise to cope with all kinds of objects, then you have selected a wrong tool for the job. Perhaps you want to give generic programming a try.
template <typename T>
class FileBuilder {
virtual void build (const T& t) = 0;
};
class SpecialBuilder: public FileBuilder<SpecialObject> {
void build (const SpecialObject& t) override;
};
Now the code above won't work, we need to fix it
FileBuilder<SpecialObject>* builder = GetBuilder<SpecialObject>(); // we know exactly what we want to build
SpecialObject some;
builder->build(some); // will work;
OtherSpecialObject other;
builder->build(other); // sorry that's not in the contract, won't compile
I don't fully understand why this should not be possible. SpecialFileBuilder respects the interface FileBuilder, and everywhere which expects a FileBuilder can instead be given a SpecialFileBuilder
You may have covariant return type.
But for argument, you would need contra-variant return type (which is not supported in C++).
As following code should be correct
SpecialFileBuilder specialFileBuilder;
FileBuilder& fileBuilder;
SpecialObject2 specialObject2; // Other derived class, unrelated to SpecialObject
Object& object = specialObject2;
fileBuilder.build(object); // correct type
// but
specialFileBuilder.build(specialObject2); // won't compile
contra-variant parameter would be
struct Base {
virtual void f(const Cat&) = 0;
};
struct Derived : Base
{
void f(const Animal&) override; // if contra-variance was supported
};
As you know it is not possible to use the std::enable_shared_from_this and shared_from_this() pair from the constructor of an object since a shared_pointer containing the class is not yet in existance. However, I really would like this functionality. I have attempted my own system and it seems to be working OK.
namespace kp
{
template <class T>
void construct_deleter(T *t)
{
if(!t->_construct_pself)
{
t->~T();
}
free(t);
}
template <class T, typename... Params>
std::shared_ptr<T> make_shared(Params&&... args)
{
std::shared_ptr<T> rtn;
T *t = (T *)calloc(1, sizeof(T));
t->_construct_pself = &rtn;
rtn.reset(t, construct_deleter<T>);
t = new(t) T(std::forward<Params>(args)...);
t->_construct_pself = NULL;
t->_construct_self = rtn;
return rtn;
}
template <class T>
class enable_shared_from_this
{
public:
std::shared_ptr<T> *_construct_pself;
std::weak_ptr<T> _construct_self;
std::shared_ptr<T> shared_from_this()
{
if(_construct_pself)
{
return *_construct_pself;
}
else
{
return _construct_self.lock();
}
}
};
}
Can anyone spot any flaws in this logic? I basically use placement new to assign a pointer to the shared_ptr inside the class before the constructor calls.
As it stands I can use it as so:
std::shared_ptr<Employee> emp = kp::make_shared<Employee>("Karsten", 30);
and in the Employee constructor:
Employee::Employee(std::string name, int age)
{
Dept::addEmployee(shared_from_this());
}
Before I commit this to a relatively large codebase, I would really appreciate some ideas or feedback from you guys.
Thanks!
I know it's been a while but that might be useful to someone with the same issue : the main problem will happen if you attempt to inherit from a class inheriting your enable_shared_from_this.
Especially with this line :
t->_construct_pself = &rtn;
If you have let's say :
class Object : public kp::enable_shared_from_this<Object> {
};
class Component : public Object {
};
Then the compiler won't be able to cast std::shared_ptr<Component>* to std::shared_ptr<Object>* as for the compiler those types are not related even though Component inherits Object.
The easiest solution I see would be to turn _construct_pself to void* like so :
template <class T>
class enable_shared_from_this
{
public:
void* _construct_pself{ nullptr };
std::weak_ptr<T> _construct_self;
std::shared_ptr<T> shared_from_this() const
{
if (_construct_pself)
{
return *static_cast<std::shared_ptr<T>*>(_construct_pself);
}
else
{
return _construct_self.lock();
}
}
};
And then do
t->_construct_pself = static_cast<void*>(&rtn);
It's not very sexy and might make other issues arise but it seems to be working...
[EDIT] There is a slightly better and more "C++" alternative, sorry for not thinking about it right away, just do :
t->_construct_pself = reinterpret_cast<decltype(t->_construct_pself)>(&rtn);
[EDIT2] Make shared_from_this const as it does not change anything in the class
[EDIT3] Found an other issue : If you use a copy constructor via make_shared and use operator= inside the constructor before shared_from_this, shared_from_this will return the address of copied object, not of the object's copy. Only solution I see is to define empty copy constructor and assignment operator for enable_shared_from_this and explicitly call the copy constructor from inheriting classes everytime needed... Either that or MAKE SURE you NEVER call operator= before shared_from_this inside your copy constructor.
I think there is a semantically problem with using shared_from_this() inside the constructor.
The issue is when an exception is being thrown there is no valid object, but you already have setup a shared pointer to it. e.g.:
Employee::Employee(std::string name, int age)
{
Dept::addEmployee(shared_from_this());
if (...) throw std::runtime_error("...");
}
Now Dept will have a pointer to this object, which wasn't successfully created.
Use of shared_from_this() in a constructor should be a code smell, even if it worked, because it is a sign of a possible circular dependency and/or use of a pointer to an incomplete object.
One typically calls shared_from_this() to pass a smart pointer to this object to another object. Doing this during construction would mean that "this" class depends on another component, which depends on "this" class.
Even in the (arguably) valid use case of an object self-registering at some other component, one would be registering an object that is not yet fully constructed, which is a recipe for problems, as pointed out, for example, in this answer.
The solution I would recommend is therefore to analyze the code or design and look for possible circular dependencies, then break that cycle.
In the "self-registering object" use case, consider moving the responsibility of registration somewhere else, for example, to the same place where the object is being instantiated. If necessary, use a "create" function or factory rather than direct construction.
I have some classes:
class Base
{
public:
virtual void Something() = 0;
}
class A : public Base
{
public:
virtual void Something() { /*...*/ }
void SpecialActionForA();
}
class B : public Base
{
public:
virtual void Something() { /*...*/ }
void SpecialActionForB();
}
and an array:
Base* MyMembers[2];
MyMembers[0] = new A;
MyMembers[1] = new B;
and I want to do:
A* pointer_to_a = Get(0);
B* pointer_to_b = Get(1);
Is there any good way to implement this Get() function?
My solution is:
template <typename T>
T* Get(int index)
{
return dynamic_cast<T*>(MyMembers[index]);
}
But first thing is that I have to write
A* pointer_to_a = Get<A>(0)
Which requires an additional <A>;
Second thing is that if somehow the new is screwed up like:
MyMembers[0] = new B;
Then the Get() is failed.
What I want is something like an automatic mechanism which can maps index 0 to A.
Extra details:
Actually I have 80 different classes derived from Base (They are my User Interfaces),
and my need is to get the real classes (the real UIs) to do things.
The functions I need to use are the above SpecialActionForA()...etc.
The Something() is also used, but is in the initialization stage of these UIs, or something managed by the UI manager system.
You cannot do unknown* Get(int) in principle as it will require two or more functions having the same name but differing only by return value. C++ explicitly prohibits this.
The closest function that you can get is this:
template <typename T> T* Get() {
static T* instance = new T;
return instance;
}
so you will be able to use it as:
A *a = Get<A>();
B *b = Get<B>();
Overloading of function works by looking up the argument list. It is not possible to understand what kind of the value you want by judging only the return type. Thus compiler forces you to give extra detail to instantiate the template. So your options are:
Base *Get(int N) {
return MyMembers[N];
}
or
A *GetA(int N) {
return MyMembers[N];
}
B *GetB(int N) {
return MyMembers[N];
}
or
template <typename T> void Get(int N, T *&item) {
item = (T*)MyMembers[N];
}
A* pointer_to_a;
B* pointer_to_b;
Get(0, pointer_to_a);
Get(1, pointer_to_b);
or your own
template <typename T>
T* Get(int index)
{
return dynamic_cast<T*>(MyMembers[index]);
}
Without knowing your usage scenario, it'll be a bit hard to provide a useful answer, but I actually do believe what you want is type matching. So what you do is that you pass your variables around as Base pointers until I you actually need to know the concrete underlying type, at this point you do a matching on the underlying type of your base pointer. This is works pretty much alike a switch statement mixed with lambdas, I'll try to provide an example.
...
Base* ptr = some_argument;
// Here we need the underlying type, so we'll do a match
Match(ptr)
{
Case(A* a)
{
// this is invoked if ptr happened to hold an A, now do something A specific.
}
Case(B* b)
{
// this is invoked if ptr happened to hold a B, now do something B specific
}
Otherwise()
{
// this is invoked whenever none of the above are
}
}
EndMatch;
...
This is an alternative to the usual solution, which is virtual pointers in the base class, and overriding. Note that type matching is commonly used in functional languages. For C++ there's a cleaver solution to achieving this, by Yuriy Solodkyy one of Bjarne Stroustrup's PhD students.
The short introductury paper can be found here;
https://parasol.tamu.edu/~yuriys/papers/OPM13EA.pdf
For a more information, check out hvis paper, which was presented to the ISO comitee; Open and Efficient Type Switch for C++ by Stroustup, Dos Reis and Solodkyy
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3449.pdf
For the source code behind these papers goto Yuriys homepage at;
https://parasol.tamu.edu/~yuriys/pm/
If the number of classes you've got is truly closed, then consider using closed algebraic data types, as with boost::variant.These are have a few advantages over the unrestricted open algebraic data types, in that the compiler can usually ensure exhaustive matching, and in that the closed nature allows for more optimized pattern matching implementations, though at the cost of flexibility.
Also do note that boost::variant works nicely on C++03!
Do however please consider if you really need pattern matching or polymorphic dispatching. Both approaches are advantages and downsides, the main advance of the pattern matching approach, is that you aren't required to change your classes, and that you avoid polluting your base class with ultra specific virtual methods, which may only be called in a single location.
I want to pass this as argument to member variable like this:
template<class T>
struct fun
{
fun(T* pointer) : memberPointer(pointer)
{
}
T* memberPointer;
};
struct gun
{
gun() : member(this)
{
}
fun<gun> member;
};
In Visual Studio I have next warning: warning C4355: 'this' : used in base member initializer list
Can you please explain why is it wrong to do this? I just store the pointer in member constructor to use it later to call some gun functions from fun.
The potential problem is that this points to an object that has not been fully constructed. So for example if you had this:
template<class T>
struct fun
{
fun(T* pointer) : memberPointer(pointer)
{
memberPointer->callMethod(); //this is 2nd to execute
}
T* memberPointer;
};
struct gun
{
gun() : member(this) //this is 1st to execute
{
ptr = new char(); // this is 4rd to execute unless earlier UB prevents execution
}
void callMethod()
{
printf("%s", ptr); //this is 3rd to execute, you get UB here
}
fun<gun> member;
char* ptr;
};
you would run into undefined behavior because you would pass a pointer to a not fully constructed object where only a pointer to a fully constructed object should be passed. I intentionally crafted some crappy code with UB to be more convincing, in real life you won't necessarily have UB as a problem, sometimes all the objects will be in valid states so you will get some really subtle initialization order bugs.
That's not your case. Your case is fine - you don't care that the object is not yet fully constructed. However you should be careful when changing your code so that you don't get into scenario as above.
It's only a warning. If you were to deference this inside the fun constructor then you would be accessing an uninitialised object. But you aren't, you are only storing the pointer, so you can ignore the warning. If you want to turn off the warning then add this at the top of your code
#pragma warning (disable: 4355)
It is not completely wrong, but as you pass the pointer, your gun object might not be fully constructed yet. Hence, it might happen that you call methods in the base class that rely on the complete construction of your object.
What you want is to achieve static polymorphism, which is best handled through the curiously recurring template pattern (CRTP). In your case, you're almost there:
template<class Base>
struct fun : public Base
{
void foo()
{
// call gun function
Base::bar();
}
};
struct gun : public fun<gun>
{
void bar()
{
/*...*/
}
};
In my application I have to derive some classes from a base one, the problem is that I want to enforce the derived classed to have 3 particular constructor implementation. As c++ don't have virtual pure constructor, it seemed quite desperate (I had to check manually each class implementation to ensure that the particular ctors are implemented, not quite fun to do).
Yesterday I found a crazy way to simulate the comportment of a virtual ctor:
template <class T>
class AbstractEnforcer{
protected:
AbstractEnforcer(){}
private:
static void Enforcer(){
delete new T();
delete new T(*(new unsigned int));
delete new T(*(new unsigned int, *(new QString));
}
}
class AbstractClass : private AbstractEnforcer<AbstractClass>{
}
the only inconvenience with this approach is that I have to to declare all derived class with the syntax:
class X : private AbstractEnforcer<X>
And even if it's not a problem; because the Enforcer() methode never get called (and even so it does nothing [hope so!!!])
My question is:
"is there any mean (not with macros) to force the derived class to use this mechanism without parametrazing the AbstractClass (because this will work in only one level of derivation"
template <class T>
class AbstractClass : private AbstractEnforcer<T>{
}
Your solution does not solve the problem since templated code that isnt used is not instantiated, and thus unless you manually invoke this function - it will not verify the existence of the wanted constructors.
What you can do is have this method called from the constructor of your enforcer:
template <class T>
class AbstractEnforcer{
protected:
AbstractEnforcer(){ Enforcer(); }
private:
static void Enforcer(){
delete new T();
delete new T(*(new unsigned int));
delete new T(*(new unsigned int, *(new QString)));
}
// disable:
AbstractEnforcer (const AbstractEnforcer &enf);
};
class AbstractClass : private AbstractEnforcer<AbstractClass>{
};
int main () {
AbstractClass c;
}
Then, the compiler complains - mission accomplished.
Note that I've disabled the copy constructor so that there will be no way to bypass that check (by calling a different constructor).
Edit - Non leaking Enforcer(): [As there's absolutly no need to use dynamic allocations there..]
static void Enforcer(){
T t1();
T t2(int(3));
T t3(int(4), QString());
}
See this page in the C++ FAQ.
What I would do is something like this:
class AbstractClass {
public:
virtual AbstractClass* create() const = 0;
virtual AbstractClass* create(unsigned int) const = 0;
virtual AbstractClass* create(unsigned int, QString) const = 0;
};
Then each of the derived classes would be forced to override these functions, which should create new objects with different constructors.
From this comment to one of the answers I think that you do not really want to achieve what you are asking here, but rather a different thing. The comment I refer to is:
Part 1:
I knew that we can't have a virtual
constructor and I don't want to have
one, my purpose is to a compiler
static code checking that will alert
me if I forgot to implement a specific
constructor prototype.
Part 2:
My project is a
plugin like dynamic loading system and
I have in some way enforce the ctors
prototypes implementation of the third
party code.
What you are asking in the question is 1, and you can enforce it in different ways, just read some of the answers, or take a look at metaprogramming examples and the boost::type_traits library.
Now, if what you really want is part 2: provide a dynamic loading plugin mechanism then you do not need to enforce the constructors, but a common interface both for the plugin objects and the creation of the plugin objects. There is no way of instantiating an instance of an object of unknown (at compile time) object, and that means that you will not be able to call the constructors from your code. I would suggest
// Interface:
class plugin {
public:
virtual void operation() = 0;
};
class plugin_factory {
public:
virtual plugin* create() = 0;
virtual plugin* create( unsigned int ) = 0;
virtual plugin* create( unsigned int, QString const & ) = 0;
};
Users will need to provide the implementation of a plugin and the factory that creates them. They will probably need to implement a point of entry for their library so that you can get access to the factory (or so they can register their factory within your system, or else I would suggest using a library for these purposes (boost::extension seems like a place to look at)
I'd probably just have a template for generating a test:
template <typename T>
void enforceConstructors() {
T t1;
T t2(0);
QString q;
T t3(0, q);
}
Then somewhere in your tests, do:
enforceConstructors<X>();
enforceConstructors<Y>();
enforceConstructors<Z>();
Those might be all together, or in separate places for each of the classes X, Y, Z. Depends how you want to organise your tests.
If the values I used aren't suitable, either put in some values which are, or else compile that test but don't run it. If you don't have unit tests either get some, or else add the following to the class (instead of inheriting from the base class):
#ifndef NDEBUG
static void test() { enforceConstructors<X>(); }
#endif
You don't usually need to make constructors part of an interface defined by an abstract base class. The reason is that such interfaces are for dynamic polymorphism - you pass an object to some function, and it calls functions on it. You can't "pass" a class to a function and have it instantiate the class other than with templates. Templates mostly enforce their interfaces at compile time anyway - if you instantiate the template and it uses the constructor, then the constructor has to be there.
If you forget to implement the constructor but use it in your code, you will get a compilation error. For example:
Base * p = new Derived( 42 );
will be a compile-time error if the Derived(int) constructor is not provided - the Base constructor will not be used.
I finally adopted this solution, but not quit convienced:
#ifdef NDEBUG
#ifndef ENFORCE_CTORS
#define ENFORCE_CTORS(enforcingTemplate, enforcedClass) \
friend void enforcingCtors(){static enforcingTemplate<enforcedClass> _enforcer;}
#endif
template<class T>
class AbstractEnforcer : T{
public:
explicit AbstractEnforcer(){
T enforcedCtor0( );
T enforcedCtor1( *(new unsigned int) );
T enforcedCtor2( *(new unsigned int), *(new QString) );
T enforcedCtor3( *(new unsigned int), *(new float ) );
}
};
#endif
and in each class that I wan't to enforce I just add like this:
class X{
ENFORCE_CTORS(AbstractEnforcer, X);
/*
.....
*/
}
I didn't find any other way to inject this code dynamically in a class. And I may been unclear about the final purpose of the operation (sorry for my terrible English).