Inheritance - initialization problem - c++

I have a c++ class derived from a base class in a framework.
The derived class doesn't have any data members because I need it to be freely convertible into a base class and back - the framework is responsible for loading and saving the objects and I can't change it. My derived class just has functions for accessing the data.
But there are a couple of places where I need to store some temporary local variables to speed up access to data in the base class.
mydata* MyClass::getData() {
if ( !m_mydata ) { // set to NULL in the constructor
m_mydata = some_long_and complex_operation_to_get_the_data_in_the_base()
}
return m_mydata;
}
The problem is if I just access the object by casting the base class pointer returned from the framework to MyClass* the ctor for MyClass is never called and m_mydata is junk.
Is there a way of only initializing the m_mydata pointer once?

It doesn't have members and you must maintain bit-for-bit memory layout compatibility… except it does and C++ doesn't have a concept of freely-convertible.
If the existing framework allocates the base objects, you really can't derive from it. In that case, I can think of two options:
Define your own class Cached which links to Base by reference. Make the reference public and/or duplicate Base's interface without inheritance.
Use a hash table, unordered_map< Base *, mydata > mydata_cache;. This seems most appropriate to me. Use free functions to look up cache data before delegating to the Base *.

You could initialize your private variables in a separate initialization member function, so something like this:
class MyClass {
public:
init() {
if (!m_mydata) {
m_mydata = f();
}
}
};
framework_class_t *fclass = framework.classfactory.makeclass();
MyClass *myclass = (MyClass*)fclass;
myclass->init();
char *mydata = myclass->getData();
It's hard to say if this is a good idea or not without knowing what framework you're using, or seeing your code. This is just the first thing that came to mind after reading your description.

You could create a wrapper for the factory of the framework. The wrapper would have the same interface, delegate calls to the framework but it could initialize the created base class instance before returning it. Of course, this requires you to change your code to use the wrapper everywhere, but if it is possible, after that you can be sure that the initialization happens properly.
A variation on this: use RAiI by wrapping the base class instances into a custom autopointer which could do the initialization in its constructor. Again, if you manage to change the code everywhere to use the new wrapper type instead of the derived class directly, you are safe.

Related

Trying to manually creating unique_ptr class instances with virtual parts

As a Master Thesis I need to expand the database duckdb on github with functionality.
One of the first steps was to create a fixed internal plan that represents something like "select 42;" just on physical level. To that end I tired to manually create such a plan with the classes used internally by duckdb.
On compiling I generally get an error message like this:
/home/ubuntu/git/duckdb/src/include/common/helper.hpp: In instantiation of ‘std::unique_ptr<T> duckdb::make_unique(Args&& ...)
[with T = duckdb::Expression; Args = {duckdb::ExpressionType,
duckdb::ExpressionClass, duckdb::TypeId}]’:
/home/ubuntu/git/duckdb/src/execution/physical_plan_generator.cpp:125:155:
required from here
/home/ubuntu/git/duckdb/src/include/common/helper.hpp:24:23: error:
invalid new-expression of abstract class type ‘duckdb::Expression’
return unique_ptr<T>(new T(std::forward<Args>(args)...));
The creation was this line:
unique_ptr<Expression> ProjectionExpression = make_unique<Expression>(ExpressionType::VALUE_CONSTANT, ExpressionClass::BOUND_CONSTANT, TypeId::INTEGER);
The constructor is
Expression::Expression(ExpressionType type, ExpressionClass expression_class, TypeId return_type)
: BaseExpression(type, expression_class), return_type(return_type) {
}
with baseexpression being
BaseExpression(ExpressionType type, ExpressionClass expression_class)
: type(type), expression_class(expression_class) {
}
virtual ~BaseExpression() {
}
As you can see the class expression uses an initialization list from class baseExpression. As Far as I can tell there is no direct inheritance between the 2 but clearly I need something that is currently missing to correctly initialize the constructor.
The problem is that normally in duckdb these things come from the parser and get then built from these objects. And I have to try and guess how the data structure is supposed to look like.
I am having problems figuring out how to directly allocate this object with make_unique because expression clearly requires a baseExpression of somekind but baseexpression itself has a virtual component so I can't just create that one directly either.
basically what I am asking is: How do you make a new unique_ptr object when the class is abstract?
How do you make a new unique_ptr object when the class is abstract?
By creating an instance of a concrete non-abstract subclass, and returning that as a pointer the to abstract base class. This is common practice when using the Factory pattern and similar idioms.
Looking into the source code at here, you see that Expression has a pure virtual member function (recognizable by virtual and the = 0):
class Expression : public BaseExpression {
//...
virtual unique_ptr<Expression> Copy() = 0;
//...
};
A class with a pure virtual member function is an abstract class. Instances of abstract classes can not be created (whether as variables with automatic storage duration, with new or with std::make_unique). Instead you need to choose the appropriate class derived from Expression that implements all pure virtual methods and create an instance of that class, e.g. by calling std::make_unique<DerivedClass>(...). You can still assign that to std::unique_ptr<Expression> afterwards.
The problem is not virtual member functions in general, only pure virtual member functions. Without pure virtual member functions, classes with virtual functions can be used with std::make_unique without problem.

Return a shared_ptr from a class C++

I have a question which has to do with returning a shared pointer from a class.
Part of my class looks like this:
typedef std::shared_ptr<IBaseInterface> IBaseInterfaceSP;
...
IBaseInterfaceSP getMyInterface()
{
m_spBase = std::make_shared<IBaseInterfaceSP>( m_derivedInterface);
return m_spBase;
}
where both m_derivedInterface and m_spBase are private members of my class, i.e:
private:
IBaseInterfaceSP m_spBase ;
DerivedInterface m_derivedInterface;
Also, DerivedInterface inherits from IBaseInterfaceSP.
getInterface is a public function of my class.
Is this the right way to return a pointer from my class? Will there be any problems with slicing or anything similar?
P.S. I am sorry if something is unclear ( I am not allowed to post all the code here in public, only some parts), if so, just let me know.
I can see several problems with this code.
1. Lazy initialization
Each time you call getInterface, you create a new instance of your IBaseInterface class. As a user of your class, I would not expect this behavior from a method called "get".
I guess you wanted to implement lazy initialization, in which case you would do it like this:
IBaseInterfaceSP getInterface()
{
if (!m_spBase)
{
m_spBase= std::make_shared<IBaseInterface>( m_derivedInterface );
}
return m_spBase;
}
2. Naming conventions
You are instantiating a class called IBaseInterface, which sounds like an abstract class (the "I" prefix was historically used for interfaces). You should probably rename your class so that it doesn't sound abstract. Also, the "I" prefix is redundant with the "Interface" suffix.
However, in what I consider "good" OOP, users do not need to know that you are handing them an interface. There is thus no need for a naming convention that differentiates concrete from abstract classes.
3. Ownership semantics
Shared pointers are meant for shared ownership: when you return a shared pointer, you are telling the users of your class that they will own the returned object, too. Usually, that is not needed. In most cases you would return a non-owning pointer, a.k.a. raw pointer. For example:
IBaseInterface* getInterface()
{
return m_spBase.get(); // Instantiation done elsewhere, for example in constructor
}
4. Slicing
There is indeed slicing happening here. This line:
m_spBase = std::make_shared<IBaseInterface>( m_derivedInterface );
Actually expands to code that contains something equivalent to this:
auto newInstance = new IBaseInterface(m_derivedInterface );
In turn, the line above will call the copy constructor of the IBaseInterface class, whose signature is similar to:
IBaseInterface(IBaseInterface& other)
Thus, m_derivedInterface is interpreted as an IBaseInterface reference in the context of that call. Only the members of IBaseInterface will thus be copied during the call to "new", thereby losing all the information stored in the derived class, DerivedInterface.
All that said, it seems to me that what you really want is direct access to the m_derivedInterface object. What you are doing right now is, you copy the instance into another object and return the new object. I think what you really want is this:
IBaseInterface* getInterface()
{
return &m_derivedInterface;
}
If you insist on using shared ownership, just store a shared pointer to m_derivedInterface instead of a value:
MyClass(Args args)
{
m_derivedInterface.reset(new DerivedInterface(args));
}
std::shared_ptr<IBaseInterface> getInterface()
{
return m_derivedInterface;
}
std::shared_ptr<IBaseInterface> m_derivedInterface;

C++: Incorporating inheritance, polymorphism, and factories

I'm currently trying to make a pair of classes which depend on each other. Essentially, objects of class B create objects of class A. However, I am also using an inheritance hierarchy, so all derivatives of class B must also be able to create derivatives of class A (each derivative of B corresponds to a derivative of A, so DerB1 makes DerA1 objects, and DerB2 makes DerA2 objects).
I'm having problems with my implementation, and it may be silly, but I would like to see if anyone knows what to do. My code is below (I HATE reading other people's code, so I tried to make it as easy to read as possible...only a few important bits, which I commented to explain)
class BaseB {} // Declare BaseB early to use in BaseA constructor
class BaseA
{
public:
BaseA(BaseB* b) {}; // Declare the BaseA constructor (callable by all B classes, which pass a pointer to themselves to the constructor so the A objects can keep track of their parent)
}
class DerA:public BaseA
{
DerA(BaseB* b):BaseA(b) {}; // Inherit the BaseA constructor, and use initialization list
}
class BaseB
{
public:
virtual BaseA createA() = 0; // Virtual function, representing method to create A objects
}
class DerB:public BaseB
{
BaseA createA() {
DerA* a = new DerA(this); // Definition of createA to make a new A object, specifically one of type DerA (Error1: No instance of constructor "DerA::DerA" matches the argument list)
return a; // Error2: Cannot return DerA for BaseA function
}
}
So, I have two main problems, one is practical (Error1, as I seem to simply be calling the function wrong, even if I try to typecast this), one is philosophical (Error 2, as I don't know how to implement the features I want. If anyone could point out why Error1 is occurring, that would be wonderful! Error2, however, requires some explanation.
I would like my user (programmer) to interact with all A objects the same way. They will have the same exact public functions, but each will have VERY different implementations of these functions. Some will be using different data types (and so will require function contracts), but many will have the same data types just with different algorithms that they use on them. I would like some piece of code to work exactly the same way if one class A derivative is used or another is. However, in my current implementation, it seems that I need to return a DerA object instead of a BaseA object (at the site of Error2). This means that I will need to write a segment of main code SPECIFICALLY for a DerA object, instead of any arbitrary A object. I would like something like:
BaseB b = new DerB(); // Declare which derivative of BaseB I want to use
BaseA a = b->createA(b); // Call the createA function in that derivative, which will automatically make a corresponding A object
This way, I can simply choose which type of B object I would like in the first line (by my choice of B constructor, or tag, or template, or something), and the rest of the code will look the same for any type of object B (as each has the same public member functions, even though each object will perform those functions differently).
Would I be better off using templates or some other method instead of inheritance? (I apologize for being intentionally vague, but I hope my class A/B example should mostly explain what I need).
Thank you for any help. I apologize for asking two questions in one post and for being long-winded, but I am trying to learn the best way to approach a rather large redesign of some software.
You have several syntactical issues to get the errors solved:
Add the ; after each class definitions.
The first line should be a forward declaration: class BaseB /*{} NO!!*/ ;
Add public: to make constructor of DerA accessible for DerB
BaseA createA() should return a value, not a pointner (according to signature): return *a;
There is another potential hidden slicing issue, as createA() returns a value, an not a pointer. This means that your returned object (here *a), would be copied but as a real BaseA object. So only the BaseA part of the object will be copied, not the derived part. This could lead to some unexpected surprises.
In order to avoid slicing, consider returning a pointer, changing the signature of createA() accordingly. The object pointed to would then keep the right type without loosing anything.
If you would later need to copy the object, you could use a static cast if you are absolutely sure of the real type of the object pointed to:
BaseA *pba = pdb->createA(); // get pointer returned
DerA da = *static_cast<DerA*>(pba); // static cast with pointer
If you would need to copy pointed BaseA objects without necessarily knwowing for sure their real type, you could implement a virtual clone function in DerA (e.g. prototype design pattern)

Gradually construct an object

Suppose there is a hierarchy of two classes (class Derived: public Base). Both these classes have big memory footprint and costly constructors. Note that nothing in these classes is allocated in heap: they just have a big sizeof.
Then there is a function with a fast path (executed always) and a slow path (executed conditionally). Fast path needs a Base instance, and slow path needs a Derived instance constructed from existing base. Also, slow path decision can be made only after the fast path.
Current code looks like this:
void f()
{
Base base;
/* fast path */
if (need_slow_path) {
Derived derived (base);
/* slow path */
}
}
This is inefficient, because the base needs to be copied into derived; also the base is allocated twice and there is a risk of overflowing the stack. What I want to have:
allocate memory for Derived instance
call Base ctor on it
execute the fast path
if needed, call Derived ctor on the existing Base instance and execute the slow path
Is it possible in C++? If not, what are possible workarounds? Obviously, I'm trying to optimize for speed.
I am afraid this is not possible just as you wrote - any constructor of Derived must call a constructor of the Base subobject, so the only way to do that legally would be to call Base's destructor first, and I believe you don't want that.
However, it should be easy to solve this with a slight redesign - prefer composition over inheritance, and make Derived a separate class that will store a reference (in the general sense; it can of course be a pointer) to Base and use it. If access control is an issue, I feel a friend is justified here.
You should change your design slightly to change your reliance on inheritance to that on composition.
You could encapsulate members of derived class (not present in the base class) into another class, and keep it's null reference in the derived class.
Now directly initialize derived class without initializing new class's object.
Whenever slow path is required, you can initialize and use it.
Benefits
Inheritance relationship between derived and base class is preserved.
Base class object is never copied.
You have lazy initialization of derived class.
I can fake it.
Move/all the data of derived into an optional (be it boost or std::ts::optional proposal for post C++14, or hand rolled).
Iff you want the slow path, initialize the optional. Otherwise, leave it as nullopt.
There will be a bool overhead, and checks when you assign/compare/destroy implicit. And things like virtual functions will be derived (ie, you have to manage dynamic dispath manually).
struct Base {
char random_data[1000];
// virtual ~Base() {} // maybe, if you intend to pass it around
};
struct Derived:Base {
struct Derived_Data {
std::string non_trivial[1000];
};
boost::optional< Derived_Data > m_;
};
now we can create a Derived, and only after we m_.emplace() does the Derived_Data get constructed. Everything still lives is in one contiguous memory block (with a bool injected by the optional to track if m_ was constructed).
Not sure if you can do exacactly what you want i.e execute "fast" path before second contructor but i think you use 'placement new' feature - manually call contructors based on need_slow_path predicate. i.e but that changes flow a little:
allocate memory for Derived instance
call Base or Derived ctor on it
execute the fast path
execute the slow path (if needed(
The example code
#include <memory>
void f(bool need_slow_path)
{
char bufx[sizeof(Derived)];
char* buf = bufx;
Derived* derived = 0;
Base* base = 0;
if (need_slow_path ) {
derived = new(buf) Derived();
base = derived;
} else {
base = new(buf) Base();
}
/* fast path using *base */
if (need_slow_path) {
/* slow path using *base & * derived */
}
// manually destroy
if (need_slow_path ) {
derived->~Derived();
} else {
base->~Base();
}
}
Placement new is well described here: What uses are there for "placement new"?
Can you define move copy con't in your compiler ?
There is an excellent explanation (although a bit long ) here
https://skillsmatter.com/skillscasts/2188-move-semanticsperfect-forwarding-and-rvalue-references
I don't have experience with move semantics so I might be wrong but since you want to avoid coping the base object when passing it to the derived class move semantics should do the trick
First extract constructor code into initializing methods both for Base and Derived.
Then I would make the code similar to this:
void f()
{
Derived derived;
derived.baseInit();
/* fast path */
if (need_slow_path) {
derived.derivedInit();
/* slow path */
}
}
It's a good idea to extract classes and use composition as Tanmay Patil suggested in his answer.
And yet another hint: If you haven't done already, dive into Unit-Tests. They will help you dealing with huge classes.
Perhaps instead of a class and constructors, you need a plain-old-struct and initialization functions here. You’ll be giving up a lot of the C++ conveniences, of course, but you’ll be able to implement your optimization.

Instanceof for objects in c++ (not pointers)

If I have the following classes :
class Object { ... }
class MyClass1: public Object { ... }
class MyClass2: public Object { ... }
and a stack : std::stack<Object> statesObjects;
MyClass1 c1;
MyClass2 c2;
statesObjects.push(c1); // okay
statesObjects.push(c2); // okay
How can I pop them out and retrieve the element at the head of the stack (with top() ) without dynamic_cast , since I don't work with pointers here ?
The short answer is, that with your stack as-is you can't pop out the elements as derived-class type elements. By putting them into the stack you have sliced them to the element class of the stack. That is, only that base class part has been copied into the stack.
You can have a stack of pointers, however, and then you can use dynamic_cast provided that the statically known class has at least one virtual member function, or as the standard says, provided that the statically known class is polymorphic.
On the third and gripping hand, however, instead of the Java-like downcast use a virtual function in the common base class. Often it works to just directly have such a function. For more complicated scenarios you may have to use the visitor pattern (google it), but basically, the idea is that virtual functions are the “safe” language-supported type safe way to achieve the effect of downcasts.
You cannot pop them out to their original classes, when you assign a subclass to an instance of the superclass, it gets sliced into an instance of the superclass. i.e copies of c1 and c2 which are in the stack are now instances of Object and not their original classes
Similar to How can I make the method of child be called: virtual keyword not working?
Even if you seeminlgy store a derived class object in your class, what gets stored is only the Base class part of the object. In short You get Object Slicing.
To summarize, you cannot store derived class objects in this container. You will need to store a pointer to Base as the type of conainter and use dynamic polymorphism to acheive this.
Good Read:
What is object slicing?