I have the following test:
TestGet(): _interface(), _db(_interface)
{
_interface.get = mockGet;
}
which is used when testing this class:
class DB: public IDB
{
public:
explicit DB(Interface_T& interface):
_interface(interface)
{
}
...
private:
Interface_T _interface;
};
Interface_T is a C interface implemented in a struct and passed to me from a C api. I wish to use the DB class as a wrapper around the C interface.
Notice however that DB copies the interface object to its member _interface. Therefore the line:
_interface.get = mockGet;
has no effect from the DB objects point of view although this was the intention when I wrote the test class. How would you rewrite TestGet() to remedy this error? How would you present to the client of the DB class that it copies the value passed to it?
Presuming that your intention is for TestGet to set a member on the Interface_T object used by DB, you can:
A. Defer construction of DB:
TestGet(): _interface(), _db(NULL)
{
_interface.get = mockGet;
// Using a raw pointer here for minimalism, but in practice
// you should prefer a smart pointer type.
_db = new DB(_interface);
}
B. If you have control over the Interface_T class, you could add a constructor that initializes Interface_T::get directly. Then you could do:
TestGet(): _interface(mockGet), _db(_interface)
{
}
C. If you have control over the DB class, you could change it to share ownership of the supplied Interface_T (e.g. through boost::shared_ptr), add a constructor as in B, or add an accessor to its internal Interface_T member.
So you need the interface to be correct by the time the db get's constructed. Well, it's easy. Just create appropriate interface in a function and pass the result to the constructor:
Interface_T makeMockInterface()
{
Interface_T interface;
// I presume you will first use the C API to initialize it and than
interface.get = mockGet;
}
TestGet() : _db(makeMockInterface())
{
}
The Interface_T is returned by value from makeMockInterface, but since the underlying machine code actually returns objects by copying them to caller-provided space, most compilers will actually elide the copy and construct the object in the caller-provided space directly (this is explicitly allowed by standard).
The TestGet class does not need to have separate _interface member, because the _db contains it and they would not be shared anyway, so no point.
Edit: The DB constructor takes non-const reference, even though all it does is it copies the object and const reference is good enough for that. Fixing the constructor would be preferable, but if it's not an option, I'd cast it to non-const. That either needs two casts:
TestGet() : _db(const_cast<Interface_T &>(static_cast<const Interface_T &>(makeMockInterface())))
or a trivial template helper:
template <typename T>
T &lvalue_cast(const T &v) { return const_cast<T &>(v); }
TestGet() : _db(lvalue_cast(makeMockInterface()))
Since the temporary actually is mutable, just does not bind to non-const references as a safeguard, both are well defined.
This is based on Jan Hudec comment above:
class TestGet : public ::testing::Test
{
protected:
TestGet()
: _db(interfaceFactory())
{
}
Interface_T interfaceFactory()
{
Interface_T interface;
_interface.get = mockGet;
return interface;
}
DB _db;
};
I like this clean approach.
There are several ways, all including some kind of inversion of control.
My favourites are :
pass the object to the constructor using the reference to the interface
use the factory pattern to create the object, and return some kind of shared pointer (using interface again)
Something like this (assuming you have base abstract class):
struct Interface
{
virtual ~Interface(){}
virtual void foo() = 0;
};
struct Derived : public Interface
{
void foo(){}
};
struct A
{
A ( std::shared_ptr< Interface > obj_ ) : obj( obj_ )
{}
std::shared_ptr< Interface > obj;
};
//...
A myA( std::shared_ptr< Interface >( new Derived ) );
// ..
The above example is with passing to the constructor.
Related
I am working on a code with the following framework:
class IFirstStep // abstract interface
{
public:
virtual commonMethod1() = 0;
...
};
class FirstStepBase : public IFirstStep // Jobs common to all FirstStep's
{
public:
FirstStepBase() {}
commonMethod1() override;
...
protected:
CommonMembers;
void correctSettings()
{
somePreparations;
auto smartPtr = static_cast<std::shared_ptr<IFirstStep>>(this);
SecondStep secondStep(smartPtr);
some calculations using secondStep;
reassignment of some of commonMembers;
}
};
class FirstStep1 : public FirstStepBase
{
public:
FirstSiep1(bool fineTune)
{
commonMembers = initilizeSettings();
if (fineTune)
correctSettings();
}
private:
CommonMembers initilizeSettings() {calculate and assign commonMembers;}
};
class FirstStep2 : public FirstStepBase
...
class FirstStepN : public FirstStepBase
...
class SecondStep
{
public:
SecondStep(std::shared_ptr<IFirstStep> & firstStep) : m_firstStep(firstStep) {}
some methods which use firstStep and return some results;
firstStep itself is not changed;
};
correctSettings() is perfectly executed correcting all settings for FirstStep1 right, but crashes in MS VS debugger on exit from correctSettings() with the diagnostics:
File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp
Line: 888
Expression: _CrtIsValidHeapPointer(block)
Looks the problem is caused by casting - code crashes even if exit is carried out just after the casting. Other types of casting, including pointer casts, were not accepted by the MS VS compiler. However, the thing works flawlessly if correctSettings() is changed as follows and an appropriate constructor is added to FirstStepBase
void correctSettings()
{
std::shared_ptr<IFirstStep> smartPtr
= <std::make_shared<FirstStepBase>>(commonMembers);
SecondStep secondStep(smartPtr);
some calculations using secondStep;
reassignment of some of commonMembers;
}
I would greatly appreciate an explanation of why the first approach fails and is it possible at all to utilize in the code this pointer rather than to generate an additional FirstStepBase object? Please, assume that there is no possibility to change interface to the SecondStep.
Thank you.
In your first approach, your this is just a raw pointer, but you tried to cast it into a `shared_pointer, which has different size, different structure.
To solve this, you can try to use boost::enable_shared_from_this, which will allow you to retrieve shared pointer of an object from its own function. Then you don't have to construct another FirstStepBase object.
You can take a look here boost_shared_from_this
You cannot type-cast a raw object pointer directly to a std::shared_ptr.
What you can do, though, is derive FirstStepBase from std::enable_shared_from_this, and then FirstStepBase can call shared_from_this() when needed, eg:
class FirstStepBase : public std::enable_shared_from_this<FirstStepBase>, public IFirstStep // Jobs common to all FirstStep's
{
...
void correctSettings()
{
...
auto smartPtr = shared_from_this(); // <-- here
SecondStep secondStep(smartPtr);
...
}
};
This only works if the FirstStep... object is being managed by a std::shared_ptr to begin with, so make sure you always use std::shared_ptr when creating your FirstStep... objects.
On the other hand, if SecondStep is not meant to outlive its associated FirstStep... object, then there is no reason to pass it a std::shared_ptr<IFirstStep> to begin with, just pass it a raw IFirstStep* pointer instead:
class SecondStep
{
private:
IFirstStep *m_firstStep;
public:
SecondStep(IFirstStep *firstStep) : m_firstStep(firstStep) {}
...
};
Passing a std::shared_ptr only makes sense if SecondStep outlives all FirstStep... references and needs to keep the object alive.
"this" is casted as a shared pointer, but in this case isn't it the raw pointer
I have to work with an old class with a very clumsy interface. Since I cannot change it and am reliant to it, I want to build a wrapper, offering a clean interface. Let's say I have a class ClumsyClass. Basically, I have three approaches:
1. Reference Member
Class Wrapper {
public:
Wrapper (ClumsyClass& clumsyClass)
: m_clumsyClass(clumsyClass)
{ }
int getSmth() {
return m_clumsyClass.getSmth();
}
private:
ClumsyClass& m_clumsyClass;
}
2. Pointer Member
Class Wrapper {
public:
Wrapper (ClumsyClass* clumsyClass)
: m_clumsyClass(clumsyClass)
{ }
int getSmth() {
return m_clumsyClass->getSmth();
}
private:
ClumsyClass* m_clumsyClass;
}
3. Inheritance
Class Wrapper : public ClumsyClass {
...
}
Which approach is the "cleanest" way to implement a wrapper? I prefer the third one, but when I already have a ClumsyClass object and then create a Wrapper object (copy constructor), more memory will be needed (since an instance of the original class is necessary in my case).
I would avoid 3 as it fails to encapsulate ClumsyClass. Users of Wrapper can, intentionally or otherwise, directly access the "clumsy" interface of ClumsyClass which is what you are trying to avoid. Prefer composition over inheritance.
The differences between 1. and 2. are minor. Using a reference member makes the wrapper less flexible. The class is not assignable, you can't reseat the reference and replace it with a different instance of ClumsyClass and the member can't be null. These could be good or bad things depending on your requirements.
But as mentioned in comments, the default choice should probably be to have ClumsyClass as a by-value member of Wrapper:
class Wrapper {
public:
// possible constructors
//Wrapper(const ClumsyClass& cc) : m_clumsyClass(cc) {} // copy
//Wrapper(ClumsyClass&& cc) : m_clumsyClass(std::move(cc)) {} // move
int getSmth() { return m_clumsyClass.getSmth(); }
private:
ClumsyClass m_clumsyClass;
};
There are number of reasons why this might not be possible or desirable in your particular use case and then you can fall-back to option 1 or 2. The decision depends mostly on ownership. Should Wrapper "own" the ClumsyClass or does the instance of ClumsyClass have a lifetime outside that of Wrapper?
One potential downside of using a direct member is you can no-longer hide the implementation of ClumsyClass behind a forward declaration so you lose some of the encapsulation of ClumsyClass. It is worth noting that one way of solving this is to extract out an abstract base class "interface" that Wrapper inherits from. Something like:
class IWrapper {
public:
virtual ~IWrapper() {}
virtual int getSmth() = 0;
};
which might provide additional benefits like testability.
It seems from the constraints that you have mentioned that this could be a feasible approach:
Create an interface with the methods you like to have
struct IMyMethods
{
virtual int getOther() = 0;
...
virtual ~IMyMethods() {};
};
Now create a new class deriving from your class and the interface you want to use on the class where you add the implementation of the interface
class MyAgileClass : public ClumsyClass, IMyMethods
{
public:
MyAgileClass(/*same args as for ClumsyClass*/)
{}
~MyAgileClass()
{}
virtual int getOther()
{
return getSmth(); // clumsy class function
}
...
};
You can now either access the ClumsyClass directly or via the simplified interface
Let's assume we have interface selector_interface_t and implementation of this interface pin_selector_t.
class selector_interface_t
{
public:
virtual void select(uint8_t address) = 0;
virtual void deselect() = 0;
};
class pin_selector_t : public selector_interface_t
{
private:
uint8_t mask;
public:
pin_selector_t(uint8_t mask);
void select(uint8_t address);
void deselect();
};
And now we want to pass object witch implements this interface to class myclass_t and store for future use by other myclass_t methods (eg. strobe).
class myclass_t
{
private:
selector_interface_t * selector;
public:
myclass_t(selector_interface_t & selector);
void strobe(uint8_t pin);
};
myclass_t::myclass_t(selector_interface_t & selector) // : selector(selector)
{
// ...
}
void myclass_t::strobe(uint8_t pin)
{
this->selector->select(pin);
this->selector->deselect();
}
The only way is pass implementation by pointer or by reference. I prefer second solution and pass by reference. But I cannot simply store this reference in myclass_t object because of lifetime of object with interface implementation. It would be better to make a copy. But I cannot have selector_interface_t field member. I can only have reference or pointer to this type. On the other way I'd like to avoid using malloc. What can I do with it?
If you are the one who creates the selector_interface_t type then you can store it inside a shared_ptr and have the myclass_t class hold a weak_ptr or shared_ptr to the interface.
If you are not the one who creates selector_interface_t then I assume you have other means of keeping the object alive, wrap it in a class that manages the lifetime and that object wrap in shared_ptr.
If you can't guarantee that the implementation has the right lifetime, then you need to manage it, which means dynamically allocating it. (Using new, not malloc.)
I would strongly suggest using either shared_ptr<selector_interface_t> or unique_ptr<selector_interface_t> - depending on whether or not you ever want to share implementation objects between clients. You then get correct code with very little effort.
I have a setup with a base class that inherits from enable_shared_from_this
class Object : public enable_shared_from_this<Object>
{ ... };
I inherit from enable_shared_from_this because I need to call shared_from_this() every so often. In certain derivations of Object, I need to call shared_from_this() from with in the constructor, which can't be done:
class Thing : public Object
{
public:
Thing() : Object(...)
{ doSomething(shared_from_this()); /* error */ }
};
So a work around is two-phase construction.
class Thing : public Object
{
public:
Thing() : Object(...) { }
void Init() { /* safe to call shared_from_this here */ }
};
A valid way to create a Thing object would be:
shared_ptr<Thing> thing = make_shared<Thing>();
thing->Init();
This is not very nice and error prone but at least it works. However, now there's an issue with further inheritance:
class Bling : public Thing
{
public:
Bling() : Thing(...) { ... }
void Init() { /* safe to call shared_from_this here */ }
};
// How do we create a Bling object?
shared_ptr<Bling> bling = make_shared<Bling>();
static_cast<Thing*>(bling.get())->Init(); // horrible
bling->Init();
// Maybe Bling::Init should look like:
// Bling::Init() { Thing::Init(); /* + other stuff */ }
// then we could do:
shared_ptr<Bling> bling = make_shared<Bling>();
bling->Init(); // etc
Is there a safer or cleaner way to do this? For example, API wise its less error prone to make the constructors for Object, Thing and Bling private and use a static Init() function that creates the shared_ptr:
static shared_ptr<Bling> Bling::Init() {
auto bling = make_shared<Bling>();
Bling::init(bling);
return bling;
}
static void Bling::init(shared_ptr<Bling> bling) {
/* chain parent class init */
Thing::init(bling); // sig: Thing::init(shared_ptr<Thing>);
/* do init stuff */
}
// calls Object(), Thing(), Bling(),
// Object::init(), Thing::init(), Bling::init()
auto bling = Bling::Init();
Basically I'm looking for patterns to implement object creation in a way where I can use a shared_ptr to the object during creation. I need to allow for basic inheritance. I would like suggested methods to consider end-user ease of use and developer maintainability.
You probably should not rely on the fact that the user of an object initially always holds it in a shared pointer. Design the class such that objects are allowed on the stack and heap.
How to solve this depends on what you do with the pointer returned by shared_from_this().
The one thing that comes to my mind is that the object registers itself somewhere - i.e. outside of the object. In my opinion it is better to do that outside of the data classes derived from Object. If you have a registry object of class Registry, turn it into a factory (as suggested by David Schwartz):
class Registry;
class Object
{
protected:
Object() = default;
friend Registry;
public:
// ...
};
class Thing : public Object
{
protected:
Thing() = default;
friend Registry;
public:
// ...
};
class Registry
{
vector<shared_ptr<Object>> store;
public:
shared_ptr<Thing> CreateThing()
{
shared_ptr<Thing> newThing = make_shared<Thing>();
newThing->init(); // If you like.
store.push_back(newThing);
return newThing;
}
shared_ptr<Bling> CreateBling();
// ...
};
No need for enable_shared_from_this at all.
Easier to understand.
Responsibilities clear.
Easily changed such that unregistered Object and Thing objects are allowed. (Scratch the protected constructor and the friend declaration.)
It might already be clear, but just to be sure: I am not in favor of enable_shared_from_this. It makes the assumption, that the object is managed by a shared_ptr at the time shared_from_this() is called. If this is not the case, the "behavior is undefined". If at least it would be an exception or nullptr would be returned...
Such assumptions are ok, when the creation of the initial shared_ptr and the call of shared_from_this() are close to each other in the code (whatever that means). Does anyone have a use case for this? I don`t.
I'm working on C++ framework and would like to apply automatic memory management to a number of core classes. So far, I have the standard approach which is
class Foo
{
public:
static
shared_ptr<Foo> init()
{
return shared_ptr<Foo>(new Foo);
}
~Foo()
{
}
protected:
Foo()
{
}
};
// Example of use
shared_ptr<Foo> f = Foo::init();
However, the above breaks when I subclass Foo, since even tho init() is inherited, it still returns shared_ptr<Foo> which contains a pointer to instance of Foo.
Can anyone think of an elegant solution to this? Should I perhaps just stick with (semi-)manually wrapping instances of class with shared_ptr? This would also give ability to expose parameterized constructors without declaring new named constructors...
Ie.
template <typename T>
shared_ptr<T> make_shared(T* ptr)
{
return shared_ptr<T>(ptr)
}
// Example
shared_ptr<T>
f1 = make_shared(new Foo()),
f2 = make_shared(new Foo(1,2));
I would try something like this:
template<class T>
class creator
{
public:
static shared_ptr<T> init()
{
return(shared_ptr<T>(new T));
}
};
class A : public creator<A>
{
};
class B : public A, public creator<B>
{
public:
using make_shared<B>::init;
};
// example use
shared_ptr<A> a = A::init();
shared_ptr<B> b = B::init();
But this isn't necessarily saving you a thing compared to standalone template you proposed.
Edit: I missed previous answer, this seems to be the same idea.
I don't understand what this achieves, you don't appear to be getting any extra memory management using this init function than by simply declaring a shared_ptr.
int main( void )
{
shared_ptr<foo> a = foo::init();
shared_ptr<foo> b( new foo );
}
What's the difference. shared_ptr provides the memory management, not anything in init.
It seems that the goal is to make it impossible for users of the classes to call the constructors directly, and only expose a routine which returns shared_ptr's.
But if you want to apply this pattern, you need to replicate it in all the subclasses. The subclasses cannot automatically "inherit" init() so that init() would still call the subclass constructor, because init() is not a virtual method and is called without an object.
I would leave the constructors exposed as usual and just use the standard
shared_ptr<X> x = new X();
This keeps cognitive burden low, is readable, and remains flexible. This is how we program in our company with reference counted objects, anyway.
How about...
template<typename Derived>
class Foo
{
public:
static shared_ptr<Derived> init()
{
return shared_ptr<Derived>(new Derived);
}
~Foo()
{
}
protected:
Foo()
{
}
};
class Bar : public Foo<Bar>
{
};
int _tmain(int argc, _TCHAR* argv[])
{
shared_ptr<Bar> b = Foo<Bar>::init();
return 0;
}
Why not introduce a common base with a virtual destructor, inherit all necessary classes from it and simply use new?
It's generally not a good idea to force creation of objects using shared_ptr by hiding the constructors. I'm speaking from personal experience here working with an internal company lib that did exactly that. If you want to ensure people always wrap their allocated objects, just make sure that all arguments and members which store instances of these types expect a shared_ptr or weak_ptr instead of a naked pointer or reference. You might also want to derive these classes from enable_shared_from_this, because in a system where all objects are shared, at some point you'll have to pass the this pointer to one of these other objects' methods, and since they're designed only to accept shared_ptr, you're in pretty bad shape if your object has no internal_weak_this to ensure it isn't destroyed.
You need the static factory function in every type of the entire hierarchy.
class Foo
{
public:
static shared_ptr< Foo > instantiate( /* potential arguments */ )
{
return shared_ptr< Foo >( new Foo( /* potential arguments */ );
}
// blah blah blah
};
class Bar : public Foo
{
public:
static shared_ptr< Bar > instantiate( /* potential arguments */ )
{
return shared_ptr< Bar >( new Bar( /* potential arguments */ );
}
// blah blah blah
};
If you still have any confusion, please search CppCodeProvider on sourceforge and see how its done there.
By the way, in large C++ frameworks it's common to hide the "automatic memory management" from the coder. This lets him write shorter and simpler code. For example, in Qt you can do this:
QPixmap foo() {
QPixmap pixmap(10, 10);
return pixmap;
}
void bar() {
QPixmap a = foo(); // no copying occurs, internal refcount incremented.
QPixmap b = a; // ditto.
QPainter p(&b);
p.drawPoint(5, 5); // data can no longer be shared, so a copy is made.
// at this point 'a' is still unchanged!
p.end();
}
Like many things in Qt, this mimics the Java object model, but it goes further by implementing copy-on-write (which it calls implicit sharing). This is intended to make the API behavior less suprising to C++ coders, who aren't used to having to call clone().
This is implemented via the d-pointer idiom, which kills two birds with one stone - you provide automatic memory management, and you insulate your implementation from the user (pimpl).
You can look at the actual implementation of QPixmap here: qpixmap.cpp, qpixmap.h.