Can I have static data members in an abstract class? - c++

I designed a series of related classes, and in order to be able to manage them I made them derive from a single abstract class.
These classes all need access to a series of shared resources, and I found myself creating a vector of pointers in each, all of them identical (they necessarily must be). It seems like making a static member in the base class would give all of the derived classes access to this vector, meaning I need only build it once (it's not going to change either after it's been built, just looked up).
My question is if this is ok, and if so, how can I then build it, without calling a 'fill the vector' method from one of the derived classes?
My thinking was to do something like
class Resource {};
enumR {RES0, RES1};
class AbstractClass
{
public:
virtual void OnInit() = 0;
void static fillVector(Resource* pResource, enumR Resourcename)
{lResource[Resourcename]=pResource;};
protected:
static vector<Resource*> lResource;
};
vector<Resource*> AbstractClass::lResource;
int main()
{
Resource res0, res1;
AbstractClass::fillVector(&res0, RES0);
AbstractClass::fillVector(&res1, RES1);
return 0;
};
Then when I instantiate an object of any class derived from AbstractClass, I'd have access to the lResource vector, which is what I want.
Would this work? Is it horrible? Is it ok?

It would work, where work = compile & run.
However, all child classes will be accessing the same static vector, which means there won't be a different copy of the static vector for each child class.
For a better explanation of what I mean read the following So thread:
Are static fields inherited?
SOLUTION:
One solution is to have your parent class a template class as follows:
template<T>
class Parent<T> {
public:
static std::vector<T> sharedResource_;
}
class ChildA : Parent<ChildA> {
}
class ChildB : Parent<ChildB> {
}
In the above code, you will get a shared resource for all instances of ChildA and another one shared between instances of ChildB.
Is it right?
Well, I think it is not considered good. One of the related discussions to this is in comments to the following SO question and also under my answer to the question:
How to do "static overloaded const" in C#?

The better solution would be to just make an object with the vectors in and then only instantiate it once and give the other classes a pointer or reference to it. Static data should be absolutely avoided unless necessary and this just isn't necessary.

You can add a static function to initialise your static vector:
class AbstractClass
{
private:
// Add this
static vector<Resource*> CreateResources();
protected:
static vector<Resource*> lResource;
};
vector<Resource*> AbstractClass::lResource = CreateResources();
vector<Resource*> AbstractClass::CreateResources()
{
vector<Resource*> resources;
resources[RES0] = new Resource();
resources[RES1] = new Resource();
return resources;
}

You could try boost::assign::list_of, something like this:
vector<Resource*> AbstractClass::lResource = list_of( &res0 )( &res1 );

I have few points here.
Your vectory probably having size of 0. This could lead to some crash. You will have to allocate it before using. You can give a static or global initialize.
Do you really want a vector? Vector is appropriate when you're using some dynamic memory allocation. The enums are static. You can give a simple count and allocate it as an array.
Do you really want a static member? Static member usually used while you're sharing it between the objects of the same class. Can you satisfy the requirement with an external objects which is local/global within the class? Also can you make static function out of the class?

Since you are creataing the vector of "resource pointer" and not reserving the spaces for object in advance ,your sysetem might crash in future. Why?
Vector create a block of memory when you insert element and uses the same block until it hits its capcity. Once it hits its capcality and you inset a new element, vector will allocate a new memory (twice as previous allocated memory) and copies all the existing elements into new memory. Since this is a vector of "pointers", it is going to invaliadate all the refernces.

What I usually do in these cases is add a middle templated layer so I have a structure like this:
Define your abstract interface:
class A
{
public:
virtual ~A(){}
virtual void f() = 0
virtual A* Clone() const = 0
}
Put the resources commonly used by the child in a template and define the boiler-plate function using CRTP if necessary keeping the necessary interface function still abstract
template<class Derived>
class A_T: public A
{
public:
virtual void f() = 0;
virtual A* Clone const
{
return new Derived(dyn_cast<Derived&>(*this))
}
void ManageRes();
private:
vector myResource;
}
Finally the different concrete classes complete the implementation and do something special with those resources if necessary
class Child: public A_T<Child>
{
public:
void foo();
}

Related

How to create an array of class template?

I need to create an array of class template in C++ but compiler doesn't allow it.
Example :
class CRefBase {
public:
virtual ~CRefBase() = 0;
};
template<class T>
class CRef : public CRefBase {
private:
T *Obj;
public:
CRef(T *Obj){ this->Obj=Obj; }
}
in main function
CRefBase *refs;
refs=new CRefBase[200]; // Error in this line : cannot allocate an object of abstract type ‘CRefBase’
I see this topic but this isn't my answer.
Thanks
Even if you were to try to instantiate a derived class, it's a terrible idea, as arrays cannot be indexed in this way- when you index a pointer to CRefBase with any index other than 0, they must only ever be CRefBase, and cannot be any derived class.
Furthermore, there is a massive bunch of exception unsafety and memory leakage in the use of new[], which is banned from all reasonable codebases. It would be safe to use something like std::vector<std::unique_ptr<CRefBase>>, and then you might actually create a program that works, if you create an object of a derived class type.
CRef is a class template, CRefBase is a (non-instantiable) abstract base class.
You're not doing what the title says:
How to create an array of templated class?
Oh, and you'll need an array of poitnters for polymorphism (and a virtual base class destructor):
CRefBase **refs = new CRefBase*[200];
for(size_t i = 0; i < 200; ++i)
refs[i] = new CRef<whatever>(pointer_to_whatever_instance);
That's it. Have a nice time managing its dynamically allocated memory.
the following code means a pure virtual function so that "CRefBase" is an abstract base class, which means that it can not be instantiated!
virtual ~CRefBase()=0;
As your question, the template supp.orts array. you can first fix your compilation problem then test it again

Derived public static std::list

Will someone please point me in the correct directions. I want a "static" (singular instance) std::list, so the std::list is shared within all objects having an instance of the "Container" structure seen below. However, all other elements within the structure are to remain unique to each instance.
Where am i to place the keyword "static" for the derived std::list?
Note the keyword "static" below is misplaced, as i simply don't know where it should be in this case.
struct Container : public static std::list<int>
{
public:
Container()
{}
~Container()
{}
list<int*> Handles;
}; // struct
You don't need inheritance here; the best way to do it is to have a static member:
struct Container {
static std::list<int> list_;
}
There is no static inheritance as well, so I would propose to implement your own get, insert, remove methods that would modify internal static list.
You should not inherit from std::list; instead it seems like you want a single static member instead:
class Container
{
static std::list<int> SingleList;
// ...
}
By making a member variable static there is only one single instance of that variable, shared between all instance of the class it's declared in. Just like you want.
I believe a static member works for your case.
struct Container
{
public:
Container()
{}
~Container()
{}
public:
static std::list<int*> Handles;
}; // struct
As others have said, inheriting from standard containers is bad, and the reason this is bad is because standard containers have no virtual destructor defined. This means that upon destruction, you will not be destroying the derived object properly, when trying to destroy it through a pointer to base.
Base* b = new derived();
// do stuff
delete b; // will not destroy derived properly because base has no virtual destructor.

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; }
}

How can I decide at runtime which derived class to use as a private class member in C++?

This following question is a bit hard for me to formulate, but please bear with me, and let me know if I can help in clearing anything up.
I am writing a general-purpose simulation for 3D shapes. I am using a base class:
class Shape{
public:
...
virtual double return_volume() =0;
private:
vector<double> coordinates;
...
};
Now, since I don't know what shape the user will choose, I derive several classes from this. (e.g.: Sphere, Cube, Tetrahedron, etc.)
So far, everything is fine.
The main problem comes in the form that I have a Controller class, which launches and operates the simulation. As a private member, it should have a vector of multiple shapes (all of the same type. e.g.: 15 spheres, or 10 cubes, etc.)
class SimulationControl{
public:
void runsimulation();
private:
vector<Shape> all_shapes;
...
};
I wanted to simply initialize this private member with a non-default constructor.
Now, before I knew what I had done, Eclipse already told me that "The type 'Shape' must implement the inherited pure virtual method 'Shape::return_volume'"
I understand the error message and my mistake, of course, but I still don't understand how I can solve it.
What I would love to be able to do is to leave the type of vector undefined, and then simply create it via the constructor with the correct derived class at runtime, when I know which type of simulation the user chose.
Is is somehow possible to do that? Thanks
I'm not going to jump on the bandwagon and suggest using pointers in your container, whether smart or dumb. This is the perfect opportunity to use the PIMPL idiom.
The idea is that the class is simply a wrapper for the actual implementation, and calls a pointer to another object when a call is made to it. The pointer contained within the wrapper can be polymorphic so that it can implement the functions however it sees fit.
class Shape{
public:
Shape() { pImpl = NULL; }
Shape(const Shape& from) { pImpl = from.pImpl->clone(); }
~Shape() { delete pImpl; }
Shape& operator=(const Shape& from) { pImpl = from.pImpl->clone(); }
...
double return_volume() { return pImpl->return_volume(); }
private:
ShapeImpl * pImpl;
...
};
class ShapeImpl{
public:
...
virtual ShapeImpl* clone() const =0;
virtual double return_volume() =0;
private:
vector<double> coordinates;
...
};
Because the Shape class contains a pointer you'll need to implement the rule of three and create a destructor, copy constructor, and operator=. The defaults for the copies will certainly do the wrong thing - they'll only copy the pointer value without creating a new copy of the pimpl object to go with them. Since a vector copies elements around these functions are certain to get called.
Use (smart) pointers.
You cannot instantiate an abstract class, and even if you could, that would probably not be what you want, since you wouldn't be able to create aliases of those shapes.
You should change the definition of your SimulationControl class into something more similar to this (assuming shared ownership for your shapes here - if SimulationControl is the only owner of your shapes, rather use unique_ptr instead of shared_ptr):
#include <memory>
class SimulationControl {
public:
void runsimulation();
private:
std::vector<std::shared_ptr<Shape>> all_shapes;
...
};
Then, you could create instances of your shapes and add them to the all_shapes collection as follows (supposing MyShape is a concrete, default-constructible class derived from Shape):
std::shared_ptr<MyShape> pShape = std::make_shared<MyShape>();
pShape->set_vertices(...); // I guess the class will have a member function
// that allows setting the shape's vertices...
all_shapes.push_back(pShape);
You can only do polymorphism by pointer or reference. Try using vector<Shape*>.
Now that you are using pointers you'll have to manage the memory for them, but that is another set of questions. Try to use smart pointers if you can, or be very careful if you can't. If you are using C++11, std::vector<std::unique_ptr<Shape>> might fit the bill for you.

Creating an array of unlike objects

This is a followup to my last question wherein I need an array of objects which are child classes of one base class. I was suggested I try dynamic_cast but speed is very important in this project.
Here is essentially what I am after.
class Object
{
protected:
int id;
};
class Bike: public Object
{
public:
bike();
private:
int bells;
};
class Car: public Object
{
public:
void drive();
private:
int wheels;
};
I need an array of these objects so I decided to use the base class.
// Imagine I have 10 objects and don't know what they will be
Object* objects[10];
// Let's make the first object
objects[0] = new Car;
I was told dynamic casting was a good idea. The problem is that speed is important and I have instances where I will need to do such operations as:
Car 8 references a bike at index value 3.
Is there any other workaround without dynamic_casting?
EDIT: If I populated the array with a bunch of child classes, how could I access the data of a child class at a specific index. In other words, imagine a bike is at index 8. How could I get the int bells from that object with just the array and index.
It depends on what else you're doing, but you could have an array of structures that store an enumeration that specifies what object type it's storing along with an object pointer.
IE:
class CObject;
enum EObjectType
{
OT_Bike,
OT_Car
};
struct SObjectInfo
{
EObjectType Type;
CObject* Object;
};
When iterating through your array, you can check the type of the object, then static cast the object pointer to the appropriate derived type. I use this approach extensively where it can't be avoided and run-time identification of an object type is absolutely necessary within a generic container.
Why do you need to store objects of different classes in the same array, though, without using polymorphism and virtual methods?
First of all if you need it to be very fast do not create it on the heap with operator new. You need to create them locally if possible.
If you are sure that there will be always your objects than you can change casting to static_cast which is a lot of faster solution.
For me the best idea here is to use Interfaces with pure virtual methods. like:
Class Objects //interface
{
public:
virtual void ride() = 0;
}
and then use a interface as a base class. It is very common in the programming.
If the Objects are unlike, why have a base class?
This link might be of help: http://www.codeproject.com/Articles/23304/High-Performance-Heterogeneous-Container
It looks that your problem requires some run-time overhead, no matter how the implementation would look: this is because at some point the program needs to decide what type it actually stores. Note that you have more alternatives to introducing a bit artificial inheritance, provided you can afford using Boost:
Boost.Variant - if you know all the types that you will be storing in advance
Boost.Any - if you do not