Pass and store interface implementation - c++

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.

Related

Converting this to shared pointer and passing it as an argument to another C++ class

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

Inheritance without pointers

Suppose that I have a class with a single abstract virtual function like this:
class MyClass{
public:
virtual void MyFunc() = 0;
};
And I have no other functions, and no data members. I can also guarantee that all class which inherit from this do not have any data members and have no other functions except an implementation of MyFunc.
The biggest reason (at least in my mind) for forcing you to have a pointer to an abstract object is the size of the implementation is unknown....So is there a way to instead of having a pointer to this class just giving an instance (or pseudo instance) of the class. Take this for example:
void AFunction(MyFunc inst){ //Note the lack of pointer
inst.MyFunc(); //This should call the implementation
}
So is this even possible or am I just a wishful thinker?
You must pass either a pointer or a reference. You cannot pass by value, because that, by definition, involves making a copy of the value; and, by definition again, you can't copy an instance of an abstract class. C++ does not work this way.
So, take your pick, either:
void AFunction(MyFunc *inst){
inst->MyFunc();
}
or
void AFunction(MyFunc &inst){
inst.MyFunc();
}
Those are your options. Whether the subclasses have anything else, besides the virtual method implementation, or whether the abstract class has anything else, besides the virtual method, is irrelevant. The answer does not change.
It's not possible (without references or pointers).
class Interface {
public:
virtual void F() = 0;
};
class Implementation: public Interface {
public:
void F() {}
};
void SomeFunction(Interface x) {}
int main() {
Implementation impl;
SomeFunction(impl);
}
This is basically what you are suggesting. And if you were to compile this:
blah.cc:11:29: error: parameter type 'Interface' is an abstract class
void SomeFunction(Interface x) {}
^
You could use references, but that's basically just pointers with a different syntax.
void SomeFunction(Interface & x) {}
int main() {
Implementation impl;
SomeFunction(impl);
}
You could use std::function. You can pass it by-value without pointers but it acts like an interface for a function:
void AFunction(std::function<void()> myfunc){
myfunc(); //This will call the implementation
}
You could create this "interface" using a lambda:
MyClass mc;
auto myfunc = [mc]{mc.MyFunc();};
AFunction(myfunc);
Internally, std::function uses type erasure.
You could create your own wrapper that can be passed by value but you are probably going to need to use some sort of pointer internally.

C++: An abstract class as a member

I have a question about style. I have a class (in my case an Option) that depends on the value of an exogenous object (Interest Rate). My goal is to create a abstract base class for the exogenous object (Rate) so that I can construct variations, say SimulatedRate or ConstantRate, that will work inside my depending class, Option.
However, I'm finding in C++, since I obviously cannot instantiate a abstract base class, I must store either a pointer or a reference to the base class. My concern is that when the instantiated exogenous objects go out of scope outside of the dependent class, my dependent class will be pointing to junk.
Is there a reasonable way to utilize polymorphism for this problem in C++?
My current code:
class Dependent
{
public:
Dependent(const Exogenous& exo) : exo_(exo) {}
double getSomething() const { exo_.interfaceMethod(); }
private:
Exogenous& exo_;
}
class Exogenous
{
public:
virtual double interfaceMethod() const=0;
}
class ExogenousVariationA
{
public:
virtual double interfaceMethod() const { return resultA; }
}
class ExogenousVariationB
{
public:
virtual double interfaceMethod() const { return resultB; }
}
Your worry is valid. Since you are storing to a reference an object passed in by the client, you are trusting that client to keep the object alive while you need it. This can easily lead to problems. Of course, the same would be true if you used raw pointers to dynamically allocated objects. If the client does delete on the object before you're done with it, once again you have a problem.
The solution is to force the client to give you some kind of responsibility over the lifetime of the object. The way to do this is to ask for a smart pointer. Depending on your problem, you may want a std::unique_ptr or std::shared_ptr. Use the former if you want to take ownership from the client or the latter if you want to share ownership with them. Let's say you choose std::unique_ptr, you would then define your Dependent class as:
class Dependent
{
public:
Dependent(std::unique_ptr<Exogenous> exo) : exo_(std::move(exo)) {}
double getSomething() const { exo_->interfaceMethod(); }
private:
std::unique_ptr<Exogenous> exo_;
}
The client would use this like so:
std::unique_ptr<Exogenous> ptr(new ExogenousVariationA());
Dependent dep(std::move(ptr));
Now, when your client passes the std::unique_ptr to you, they're giving you ownership of the object. The object will only be destroyed when your std::unique_ptr is destroyed (which will be when your Dependent is destroyed, since it is a member).
Alternatively, if you take a std::shared_ptr then the object will be destroyed once both the client's and your std::shared_ptrs are destroyed.
sftrabbit has some good advice, to which I'd add:
you could create a virtual clone() method in the abstract base class (it's not a virtual base class - that's something else entirely); that method would be implemented in the derived interest rate classes, returning a pointer to a new independent interest rate object that can be owned by the Option; this is particularly useful if the objects contain data that changes as you use it (e.g. from calculations or caching)
you probably don't want this, but with std/boost shared pointers it's also possible to ask for a weak pointer to the shared object... that way you can test whether the "owners" of the object (which won't include you) have already finished with it and triggered its destruction
Separately, to use runtime polymorphism your ExogenousVariationA and ~B classes must actually derive from Exogenous, and the method you want to be polymorphically dispatched must be virtual. That looks like this:
class Exogenous
{
public:
virtual double interfaceMethod() const=0;
}
class ExogenousVariationA : public Exogenous
{
public:
double interfaceMethod() const { return resultA; }
}

Passing dependency to wrapper object via its constructor

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.

How to use automatic reference counting and virtual functions together in the C++?

I had been searching the answer for this problem for a long.
I want to use shared data (shared_ptr or something similar) where it's possible and where it's necessary of course. But I also want to use virtual functions. As you can see below, there is a contradiction in the usage of them together.
I protect the data of class in this manner:
class MyObject {
public:
void method() {
// no memory leak here, because this contains
// count of references of Data inside shared_ptr
OtherObject::otherMethod(this);
}
private:
class Data {};
shared_ptr<Data> data;
};
Because if I simply nest my class MyObject inside the shared_ptr, I will not be able to pass "this" raw pointer safely outside of the MyObject class in some method. Raw pointer is not protected with reference counting.
Example:
class MyObject {
public:
void method() {
// memory leak here, because this does not contain
// count of references of Data or of self (MyObject)
OtherObject::otherMethod(this);
}
private:
class Data {};
Data data;
};
...
shared_ptr<MyObject> crazyLeakingObject;
crazyLeakingObject leaks, because it has MyObject inside with all its data and methods, but it is only MyObject without any information about count of the references. In the MyObject's methods we have no such information.
The first approach I use when I do not need virtual functions. But the second is for the virtual functions. As you know, you can access vtable only through pointer (raw pointer) of the existing object. But raw pointers and protected shared pointers are opposites.
Usage of this two approaches together makes the architecture of my projects messy.
And there is a leaks in the second approach.
Is there a way to use virtual functions and automatic reference counting? Where I can find an examples? Did you faced with the problem?
I am not a native English speaker, so you may ask for the clarifications.
Thanks in advance.
You can use virtual functions with shared_ptr:
struct Base {
virtual ~Base() {}
void foo() { std::cout << "base\n"; }
};
struct Derived : Base {
void foo() { std::cout << "derived\n"; }
};
int main() {
shared_ptr<Base> ptr(new Derived());
ptr->foo(); // prints "derived"
} // object is deleted at function return
If your OtherObject::otherMethod stores its argument away somewhere, such that it can last longer than the caller's reference, then you might have a problem. You could pass a shared_ptr to otherMethod instead of a raw pointer, and use Boost's enable_shared_from_this so that the code in method can get the shared pointer to the object itself, to pass to otherMethod. But without seeing any of the relevant code, I don't know whether or not it's necessary or a good idea.
You want to use std::enable_shared_from_this to pass the this pointer of a shared object...
http://en.cppreference.com/w/cpp/memory/enable_shared_from_this/enable_shared_from_this