Let's say you have this:
class foo {
public:
virtual int myFunc() = 0;
///...
virtual bool who() = 0; // don't want to implement this
};
class bar : public foo {
public:
int myFunc() {return 3;}
//...
bool who() {return true;} // don't want to implement this
};
class clam : public foo {
public:
int myFunc() {return 4;}
//...
bool who() {return false;} // don't want to implement this
};
int main() {
std::vector<foo*> vec (2, NULL);
vec[0] = new bar();
vec[1] = new clam();
// copy vec and allocate new ptrs as copies of the data pointed to by vec[i]
std::vector<foo*> vec2 (vec.size(), NULL);
for ( int i=0; i<vec.size(); ++i ) {
// obviously not valid expression, but it would be nice if it were this easy
//vec2[i] = new foo(*vec[i]);
// the hard way of copying... is there easier way?
if (vec[i]->who()) {
vec2[i] = new bar ( * static_cast<bar* >(vec[i]) ) ;
} else {
vec2[i] = new clam( * static_cast<clam*>(vec[i]) );
}
}
return 0;
}
What I want is some simple way of having the compiler look up in its bookkeeping and allocating/copying vec2[i] according to the stored type of *vec[i]. The workaround is to just make a virtual function which basically returns a value specifying what type *vec[i] is, then doing a conditional allocation based on that.
A common approach goes like this:
class foo {
public:
virtual foo* clone() = 0;
};
class bar : public foo {
public:
virtual bar* clone() { return new bar(*this); }
};
class clam : public foo {
public:
virtual clam* clone() { return new clam(*this); }
};
One way you can do it is by using a dynamic cast to determine type of an object such as done here (Finding the type of an object in C++). but the easiest way would probably be to use typeid.
(assuming you want to maintain your way of using type as a determiner, otherwise I would recommend Joachim's or Igor's as better alternatives :) )
you can use the dynamic_cast to downcast and test the type,
bar* pbar = dynamic_cast<bar*>(vec[i])
if (pbar) {
vec2[i] = new bar ( * static_cast<bar* >(vec[i]) ) ;
} else {
vec2[i] = new clam( * static_cast<clam*>(vec[i]) );
}
see for more info in dynamic_cast
http://www.cplusplus.com/doc/tutorial/typecasting/
Related
class A {
protected:
int a;
public:
int getA() const
{
return a;
}
};
class B : public A
{
private:
int b;
public:
int getB() const
{
return b;
}
};
class C
{
private:
int c;
A* obj;
public:
C()
{
obj = new A[5];// obj is initialized with some values in the constructor, but i won't do it here
}
void f()
{
c += obj[0].getB();
}
~C()
{
delete obj;
}
};
The problem I am facing right now is that i want the f function to add to the variable c the value of b from the object obj[0] if the type of obj[0] is B. But if the obj[0] is A and not B I dont want anything to happen.
Is there a bool that would be 1 if a certain variable is a certain type?
I know i could overload the f function and make it take a parameter the B obj[0] and another one that takes as a paramter the A obj[0], the last function having an empty body, but i was wondering if there is a more simple/efficient way of doing it.
I have bee asked to provide an example of where I would need this specific solution so here it is
class Item
{
protected:
std::string Name;
unsigned long long Number;
bool Placeable;
};
class Tool : public Item
{
private:
long double AttackDamage;
long double AttackSpeed;
public:
long double getAttackDamage() const
{
return this->AttackDamage;
}
long double getAttackSpeed() const
{
return this->AttackSpeed;
}
};
class Mob
{
protected:
Item* Inventory;
unsigned long long InventorySize;
unsigned long long MainHand;
std::string Name;
long double AttackDamage;
long double AttackSpeed;
public:
Mob(unsigned long long n)
{
this->AttackDamage = 1;
this->AttackSpeed = 0.5;
this->InventorySize = n;
this->Inventory = new Item[this->InventorySize];
for (int i = 0; i < this->InventorySize; ++i)
this->Inventory[i] = e; // e in empty slot, like a 0 initializer for integers
this->MainHand = 0;
}
void setStats()
{
this->AttackDamage += this->Inventory[this->MainHand].getAttackDamage();
this->AttackSpeed += this->Inventory[this->MainHand].getAttackSpeed();
}
~Mob()
{
delete Invenory;
}
};
The method i need help with is void SetStats() in Mob. I want the function to only update the values of AttackDamage and AttackSpeed if the item at MainHand position is a Tool. Otherwise i dont want any updates. I could add stas to the Item class like AttackDamage and AttackSpeed and set them to 0 which would make no issue but if i would be working on a more serious project i would have more stats than AttackDamage and Speed and there would be a lot of unnecesarry memory.
This is just a fraction of the code, like not all variables are initialized and there might be some things i forgot to paste
You need at least one virtual function in the base class, otherwise there is no polymorphism. The canonical way is to define a virtual destructor:
class A {
// ...
virtual ~A() = default;
};
To use polymorphism, you can't have value types. You need pointers or references. So instead of A obj, you'd need to use A* obj. You then try to dynamic_cast obj to a B* pointer. If obj is indeed pointing to a B, the cast succeeds and returns a valid B* pointer you can use. If obj is not pointing to a B, the cast fails and returns a null pointer:
class C {
private:
int c;
A* obj;
public:
void func()
{
if (auto casted_obj = dynamic_cast<B*>(obj)) {
c += casted_obj->getB();
}
}
};
I have a class following this pattern:
class Foo
{
public:
// Create a Foo whose value is absolute
Foo(int x) : other_(0), a_(x) {}
// Create a Foo whose value is relative to another Foo
Foo(Foo * other, int dx) : other_(other), a_(dx) {}
// Get the value
double x() const
{
if(other_)
return other_->x() + a_;
else
return a_;
}
private:
Foo * other_;
int a_;
};
The Foo objects are all owned by a Bar:
class Bar
{
public:
~Bar() { for(int i=0; i<foos_.size(); i++) delete foos_[i]; }
private:
vector<Foo*> foos_;
};
Of course, this is a simplified example to get the idea. I have a guarantee that there are no loop of Foos, and that linked Foos all belong to the same instance of Bar. So far, so good. To do things the C++11 way, I would use vector< unique_ptr<Foo> > foos_; in Bar, and pass foos_[i].get() as potential argument of a Foo constructor.
There is the deal:
This a GUI application, and the user can interactively delete some Foo at will. The expected behaviour is that if foo1 is deleted, and foo2 is relative to foo1, then foo2 becomes now "absolute":
void Foo::convertToAbsolute() { a_ += other_->x(); other_ = 0; }
void usageScenario()
{
Foo * foo1 = new Foo(42);
Foo * foo2 = new Foo(foo1, 42);
// Here, foo1->x() = 42 and foo2->x() = 84
foo1->setX(10);
// Here, foo1->x() = 10 and foo2->x() = 52
delete foo1;
// Here, foo2->x() = 52
}
I know it is possible to do it using raw pointers, by using a a DAG structure with back-pointers, so the Foo are aware of who "depends on them", and can inform them before deletion (possible solutions detailed here and here ).
My question is: Would you handle it the same way? Is there a way using standard C++11 smart pointers to avoid having the explicit back-pointers, and then avoid explicitely calling areRelativeToMe_[i]->convertToAbsolute(); in the destructor of Foo? I was thinking about weak_ptr, something in the spirit of:
class Foo { /* ... */ weak_ptr<Foo> other_; };
double Foo::x() const
{
if(other_.isExpired())
convertToAbsolute();
// ...
}
But the issue is that convertToAbsolute() needs the relative Foo to still exist. So I need a non-owning smart-pointer that can tell "this reference is logically expired", but actually extends the lifetime of the referenced object, until it is not needed.
It could be seen either like a weak_ptr extending the lifetime until it is not shared with any other weak_ptr:
class Foo { /* ... */ extended_weak_ptr<Foo> other_; };
double Foo::x() const
{
if(other_.isExpired())
{
convertToAbsolute();
other_.reset(); // now the object is destructed, unless other
// foos still have to release it
}
// ...
}
Or like a shared_ptr with different level of ownership:
class Bar { /* ... */ vector< multilevel_shared_ptr<Foo> foos_; };
class Foo { /* ... */ multilevel_shared_ptr<Foo> other_; };
void Bar::createFoos()
{
// Bar owns the Foo* with the highest level of ownership "Level1"
// Creating an absolute Foo
foos_.push_back( multilevel_unique_ptr<Foo>(new Foo(42), Level1) );
// Creating a relative Foo
foos_.push_back( multilevel_unique_ptr<Foo>(new Foo(foos_[0],7), Level1) );
}
Foo::Foo(const multilevel_unique_ptr<Foo> & other, int dx) :
other_( other, Level2 ),
// Foo owns the Foo* with the lowest level of ownership "Level2"
a_(dx)
{
}
double Foo::x() const
{
if(other_.noLevel1Owner()) // returns true if not shared
// with any Level1 owner
{
convertToAbsolute();
other_.reset(); // now the object is destructed, unless
// shared with other Level2 owners
}
// ...
}
Any thoughts?
All Foo are owned by Bar. Therefore all deletions of Foo happen in Bar methods. So I might implement this logic inside Bar:
void Bar::remove(Foo* f)
{
using namespace std::placeholders;
assert(std::any_of(begin(foos_), end(foos_),
std::bind(std::equal_to<decltype(f)>(), f, _1));
auto const& children = /* some code which determines which other Foo depend on f */;
std::for_each(begin(children), end(children),
std::mem_fn(&Foo::convertToAbsolute));
foos_.remove(f);
delete f; // not needed if using smart ptrs
}
This would ensure that the expiring Foo still exists when convertToAbsolute is called on its dependents.
The choice of how to compute children is up to you. I would probably have each Foo keep track of its own children (cyclic non-owning pointers), but you could also keep track of it inside Bar, or search through foos_ on demand to recompute it when needed.
You can use the double link approach even with more than one other dependent object. You only have to link together the dependents of the same object:
class Foo {
public:
explicit Foo(double x)
: v(x), foot(nullptr), next(nullptr), dept(nullptr) {}
// construct as relative object; complexity O(1)
Foo(Foo*f, double x)
: v(x), foot(f), dept(nullptr)
{ foot->add_dept(this); }
// destruct; complexity O(n_dept) + O(foot->n_dept)
// O(1) if !destroy_carefully
~Foo()
{
if(destroy_carefully) {
for(Foo*p=dept; p;) {
Foo*n=p->next;
p->unroot();
p=n;
}
if(foot) foot->remove_dept(this);
}
}
double x() const
{ return foot? foot->x() + v : v; }
private:
double v; // my position relative to foot if non-null
Foo*foot; // my foot point
Foo*next; // next object with same foot point as me
Foo*dept; // first object with me as foot point
// change to un-rooted; complexity: O(1)
void unroot()
{ v+=foot->x(); foot=nullptr; next=nullptr; }
// add d to the linked list of dependents; complexity O(1)
void add_dept(const Foo*d)
{ d->next=dept; dept=d; }
// remove d from the linked list of dependents ; complexity O(n_dept)
void remove_dept(const Foo*d)
{
for(Foo*p=dept; p; p=p->next)
if(p==d) { p=d->next; break; }
}
static bool destroy_carefully;
};
bool Foo::destroy_carefully = true;
Here, setting Foo::destroy_carefully=false allows you to delete all remaining objects without going through the untangling of mutual references (which can be expensive).
Interesting problem. I guess you figured that you can add a pointer to the 'child' object. I am not sure, whether smart pointers help here. I tried to implement the code below using std::weak_ptr<Foo> but you can only use it for other_ and not for the listener.
Another thought I had was to leave the responsibility to some higher power. The problem that you have is that you would like to do the update when the destructor is called. Perhaps better approach would be to call convertToAbsolute() from somewhere else. For example, if you are storing the Foos in a vector and the user clicks delete in the UI, you need the index of the object in order to delete so might as well update the adjacent item to absolute value.
Below is a solution that uses a Foo*.
#include <iostream>
#include <memory>
#include <vector>
class Foo
{
public:
// Create a Foo whose value is absolute
Foo(int x) : other_(nullptr), listener_(nullptr), a_(x)
{}
// Create a Foo whose value is relative to another Foo
Foo(Foo* other, int dx) :
other_(other), listener_(nullptr), a_(dx)
{
other->setListener(this);
}
~Foo()
{
convertToAbsolute();
if (listener_)
listener_->other_ = nullptr;
}
// Get the value
double x() const
{
if(other_)
return other_->x() + a_;
else
return a_;
}
void setX(int i)
{
a_ = i;
}
void convertToAbsolute()
{
if (listener_)
listener_->a_ += a_;
}
void setListener(Foo* listener)
{
listener_ = listener;
}
private:
Foo* other_;
Foo* listener_;
int a_;
};
void printFoos(const std::vector<std::shared_ptr<Foo>>& foos)
{
std::cout << "Printing foos:\n";
for(const auto& f : foos)
std::cout << '\t' << f->x() << '\n';
}
int main(int argc, const char** argv)
{
std::vector<std::shared_ptr<Foo>> foos;
try
{
auto foo1 = std::make_shared<Foo>(42);
auto foo2 = std::make_shared<Foo>(foo1.get(), 42);
foos.emplace_back(foo1);
foos.emplace_back(foo2);
}
catch (std::exception& e)
{
std::cerr << e.what() << '\n';
}
// Here, foo1->x() = 42 and foo2->x() = 84
printFoos(foos);
foos[0]->setX(10);
// Here, foo1->x() = 10 and foo2->x() = 52
printFoos(foos);
foos.erase(foos.begin());
// Here, foo2->x() = 52
printFoos(foos);
return 0;
}
If you have a Signal/Slot framework, that provides a nice place to do the unlinking. For example, using the Qt libraries these classes could look like:
class Foo : public QObject
{
Q_OBJECT
public:
// Create a Foo whose value is absolute
Foo(int x) : QObject(nullptr), other_(nullptr), a_(x) {}
// Create a Foo whose value is relative to another Foo
Foo(Foo * other, int dx) : QObject(nullptr) other_(other), a_(dx) {
connect(other, SIGNAL(foo_dying()), this, SLOT(make_absolute()));
}
~Foo() { emit foo_dying(); }
// Get the value
double x() const
{
if(other_)
return other_->x() + a_;
else
return a_;
}
signals:
void foo_dying();
private slots:
void make_absolute()
{
a_ += other_->x();
other_ = nullptr;
}
private:
Foo * other_;
int a_;
};
Here is probably the simplest way to achieve the goal using back-pointers. You can use the container you want depending on your complexity requirements (e.g., a set, hash table, vector, linked list, etc.). A more involved but more efficient approach is proposed by Walter.
class Foo
{
public:
// Create a Foo whose value is absolute
Foo(int x) : other_(0), a_(x) {}
// Create a Foo whose value is relative to another Foo
Foo(Foo * other, int dx) : other_(other), a_(dx)
{
other->areRelativeToMe_.insert(this);
}
// Get the value
double x() const
{
if(other_)
return other_->x() + a_;
else
return a_;
}
// delete the Foo
Foo::~Foo()
{
// Inform the one I depend on, if any, that I'm getting destroyed
if(other_)
other_->areRelativeToMe_.remove(this);
// Inform people that depends on me that I'm getting destructed
for(int i=0; i<areRelativeToMe_.size(); i++)
areRelativeToMe_[i]->convertToAbsolute();
}
private:
Foo * other_;
int a_;
Container<Foo*> areRelativeToMe_; // must provide insert(Foo*)
// and remove(Foo*)
// Convert to absolute
void convertToAbsolute()
{
a_ += other_->x();
other_ = 0;
}
};
I have a struct ( can be class ) and is defined in another class as shown
struct A{
somedata_A;
somespecificimplementation_A(someclass *S1);
};
class someclass{
somedata_someclass;
A a;
};
main(){
someclass c1, *c2;
c2 = &c1;
c1.a.somespecificimplementation_A(c2);
}
How do I verify that c2 is indeed a reference for c1? Pardon me for putting up this example as it is obvious that c2 is reference for c1.
Update: A does not store a pointer to someclass
If you don't know nothing about parent, compare member' adresses
void A::somespecificimplementation_A(someclass *S1)
{
if (this == &(S1->a)) {
// parent == S1
} else {
// parent != S1
}
}
Like that:
struct A{
int somedata_A;
int somespecificimplementation_A(someclass *S1){
if ((void*) &(S1->a) == this)
{
std::cout << "S1 is a pointer to myself" << std::endl;
return 1;
}
return 0;
}
};
Assuming struct A has a pointer to c1, you can then take a pointer to c2 and compare pointer values? Similar to what you would do with assignment operator overloads?
Why go the way around and pass a pointer of your class to the nested struct which you then have to test, when you can instead give a reference to the parent by the parent during its construction?
class someclass
{
public:
struct a
{
void foo()
{
parent.doSomething();
}
private:
friend someclass;
a(someclass & parent)
: parent(parent)
{}
someclass & parent;
} a;
someclass() : a(*this) {}
private:
void doSomething()
{
}
};
Although technically unspecified, the following will work on
most modern, general purpose machines:
void A::somespecificimplementation_A( someclass* S1 )
{
char const* s = reinterpret_cast<char const*>( S1 );
char const* t = reinterpret_cast<char const*>( this );
if ( this >= s && this < s + sizeof( someclass ) ) {
// This A is a member of S1
} else {
// This A isn't
}
}
Having said that, I would stress:
This is not specified by the standard. It will work on
machines with a flat, linear addressing, but may fail (give
false positives) on a machine with e.g. segmented memory.
I'd seriously question the design if A needs to know who it
is a member of.
And if A really does need this information, it really should store
a pointer to someclass, which is passed in to its constructor, so that the dependency is manifest.
In C++, the T q = dynamic_cast<T>(p); construction performs a runtime cast of a pointer p to some other pointer type T that must appear in the inheritance hierarchy of the dynamic type of *p in order to succeed. That is all fine and well.
However, it is also possible to perform dynamic_cast<void*>(p), which will simply return a pointer to the "most derived object" (see 5.2.7::7 in C++11). I understand that this feature probably comes out for free in the implementation of the dynamic cast, but is it useful in practice? After all, its return type is at best void*, so what good is this?
The dynamic_cast<void*>() can indeed be used to check for identity, even if dealing with multiple inheritance.
Try this code:
#include <iostream>
class B {
public:
virtual ~B() {}
};
class D1 : public B {
};
class D2 : public B {
};
class DD : public D1, public D2 {
};
namespace {
bool eq(B* b1, B* b2) {
return b1 == b2;
}
bool eqdc(B* b1, B *b2) {
return dynamic_cast<void*>(b1) == dynamic_cast<void*>(b2);
}
};
int
main() {
DD *dd = new DD();
D1 *d1 = dynamic_cast<D1*>(dd);
D2 *d2 = dynamic_cast<D2*>(dd);
std::cout << "eq: " << eq(d1, d2) << ", eqdc: " << eqdc(d1, d2) << "\n";
return 0;
}
Output:
eq: 0, eqdc: 1
Bear in mind that C++ lets you do things the old C way.
Suppose I have some API in which I'm forced to smuggle an object pointer through the type void*, but where the callback it's eventually passed to will know its dynamic type:
struct BaseClass {
typedef void(*callback_type)(void*);
virtual callback_type get_callback(void) = 0;
virtual ~BaseClass() {}
};
struct ActualType: BaseClass {
callback_type get_callback(void) { return my_callback; }
static void my_callback(void *p) {
ActualType *self = static_cast<ActualType*>(p);
...
}
};
void register_callback(BaseClass *p) {
// service.register_listener(p->get_callback(), p); // WRONG!
service.register_listener(p->get_callback(), dynamic_cast<void*>(p));
}
The WRONG! code is wrong because it fails in the presence of multiple inheritance (and isn't guaranteed to work in the absence, either).
Of course, the API isn't very C++-style, and even the "right" code can go wrong if I inherit from ActualType. So I wouldn't claim that this is a brilliant use of dynamic_cast<void*>, but it's a use.
Casting pointers to void* has its importance since way back in C days.
Most suitable place is inside the memory manager of Operating System. It has to store all the pointer and the object of what you create. By storing it in void* they generalize it to store any object on to the memory manager data structure which could be heap/B+Tree or simple arraylist.
For simplicity take example of creating a list of generic items(List contains items of completely different classes). That would be possible only using void*.
standard says that dynamic_cast should return null for illegal type casting and standard also guarantees that any pointer should be able to type cast it to void* and back from it with only exception of function pointers.
Normal application level practical usage is very less for void* typecasting but it is used extensively in low level/embedded systems.
Normally you would want to use reinterpret_cast for low level stuff, like in 8086 it is used to offset pointer of same base to get the address but not restricted to this.
Edit:
Standard says that you can convert any pointer to void* even with dynamic_cast<> but it no where states that you can not convert the void* back to the object.
For most usage, its a one way street but there are some unavoidable usage.
It just says that dynamic_cast<> needs type information for converting it back to the requested type.
There are many API's that require you to pass void* to some object eg. java/Jni Code passes the object as void*.
Without type info you cannot do the casting.If you are confident enough that type requested is correct you can ask compiler to do the dynmaic_cast<> with a trick.
Look at this code:
class Base_Class {public : virtual void dummy() { cout<<"Base\n";} };
class Derived_Class: public Base_Class { int a; public: void dummy() { cout<<"Derived\n";} };
class MostDerivedObject : public Derived_Class {int b; public: void dummy() { cout<<"Most\n";} };
class AnotherMostDerivedObject : public Derived_Class {int c; public: void dummy() { cout<<"AnotherMost\n";} };
int main () {
try {
Base_Class * ptr_a = new Derived_Class;
Base_Class * ptr_b = new MostDerivedObject;
Derived_Class * ptr_c,*ptr_d;
ptr_c = dynamic_cast< Derived_Class *>(ptr_a);
ptr_d = dynamic_cast< Derived_Class *>(ptr_b);
void* testDerived = dynamic_cast<void*>(ptr_c);
void* testMost = dynamic_cast<void*>(ptr_d);
Base_Class* tptrDerived = dynamic_cast<Derived_Class*>(static_cast<Base_Class*>(testDerived));
tptrDerived->dummy();
Base_Class* tptrMost = dynamic_cast<Derived_Class*>(static_cast<Base_Class*>(testMost));
tptrMost->dummy();
//tptrMost = dynamic_cast<AnotherMostDerivedObject*>(static_cast<Base_Class*>(testMost));
//tptrMost->dummy(); //fails
} catch (exception& my_ex) {cout << "Exception: " << my_ex.what();}
system("pause");
return 0;
}
Please correct me if this is not correct in any way.
it is usefull when we put the storage back to memory pool but we only keep a pointer to the base class. This case we should figure out the original address.
Expanding on #BruceAdi's answer and inspired by this discussion, here's a polymorphic situation which may require pointer adjustment. Suppose we have this factory-type setup:
struct Base { virtual ~Base() = default; /* ... */ };
struct Derived : Base { /* ... */ };
template <typename ...Args>
Base * Factory(Args &&... args)
{
return ::new Derived(std::forward<Args>(args)...);
}
template <typename ...Args>
Base * InplaceFactory(void * location, Args &&... args)
{
return ::new (location) Derived(std::forward<Args>(args)...);
}
Now I could say:
Base * p = Factory();
But how would I clean this up manually? I need the actual memory address to call ::operator delete:
void * addr = dynamic_cast<void*>(p);
p->~Base(); // OK thanks to virtual destructor
// ::operator delete(p); // Error, wrong address!
::operator delete(addr); // OK
Or I could re-use the memory:
void * addr = dynamic_cast<void*>(p);
p->~Base();
p = InplaceFactory(addr, "some", "arguments");
delete p; // OK now
Don't do that at home
struct Base {
virtual ~Base ();
};
struct D : Base {};
Base *create () {
D *p = new D;
return p;
}
void *destroy1 (Base *b) {
void *p = dynamic_cast<void*> (b);
b->~Base ();
return p;
}
void destroy2 (void *p) {
operator delete (p);
}
int i = (destroy2 (destroy1 (create ())), i);
Warning: This will not work if D is defined as:
struct D : Base {
void* operator new (size_t);
void operator delete (void*);
};
and there is no way to make it work.
This might be one way to provide an Opaque Pointer through an ABI. Opaque Pointers -- and, more generally, Opaque Data Types -- are used to pass objects and other resources around between library code and client code in such a way that the client code can be isolated from the implementation details of the library. There are other ways to accomplish this, to be sure, and maybe some of them would be better for a particular use case.
Windows makes a lot of use of Opaque Pointers in its API. HANDLE is, I believe, generally an opaque pointer to the actual resource you have a HANDLE to, for example. HANDLEs can be Kernel Objects like files, GDI objects, and all sorts of User Objects of various kinds -- all of which must be vastly different in implementation, but all are returned as a HANDLE to the user.
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
/*** LIBRARY.H ***/
namespace lib
{
typedef void* MYHANDLE;
void ShowObject(MYHANDLE h);
MYHANDLE CreateObject();
void DestroyObject(MYHANDLE);
};
/*** CLIENT CODE ***/
int main()
{
for( int i = 0; i < 25; ++i )
{
cout << "[" << setw(2) << i << "] :";
lib::MYHANDLE h = lib::CreateObject();
lib::ShowObject(h);
lib::DestroyObject(h);
cout << "\n";
}
}
/*** LIBRARY.CPP ***/
namespace impl
{
class Base { public: virtual ~Base() { cout << "[~Base]"; } };
class Foo : public Base { public: virtual ~Foo() { cout << "[~Foo]"; } };
class Bar : public Base { public: virtual ~Bar() { cout << "[~Bar]"; } };
};
lib::MYHANDLE lib::CreateObject()
{
static bool init = false;
if( !init )
{
srand((unsigned)time(0));
init = true;
}
if( rand() % 2 )
return static_cast<impl::Base*>(new impl::Foo);
else
return static_cast<impl::Base*>(new impl::Bar);
}
void lib::DestroyObject(lib::MYHANDLE h)
{
delete static_cast<impl::Base*>(h);
}
void lib::ShowObject(lib::MYHANDLE h)
{
impl::Foo* foo = dynamic_cast<impl::Foo*>(static_cast<impl::Base*>(h));
impl::Bar* bar = dynamic_cast<impl::Bar*>(static_cast<impl::Base*>(h));
if( foo )
cout << "FOO";
if( bar )
cout << "BAR";
}
I have a raw buffer which contains number of different structs(which I couldn't modify) which I planned to wrapped inside a class like below so that I could invoke the virtual Process based on the concrete type.
class Base{
public:
virtual void Process();
};
class DerivedA : public Base {
private:
char* structBuf;
public:
virtual void Process();
}
class DerivedB : public Base {
private:
char* structBuf;
public:
virtual void Process();
}
int main()
{
for(int i = 0 ; i < 10; i++)
{
Base* a = FactoryObject();
a->Process();
}
}
My question is some of the objects depent on each other. For example, let say derivedA data would be processed first and derivedB needs the data from derivedA.
How or where could I store the derivedA object in main() so that I could utilize it in derivedB?
How could I know which objects from factory is derivedA so that I could store it?
Add a constructor to DerivedB that takes a DerivedA parameter. Construct your DerivedB instance only after you processed your DerivedA instance, passing to DerivedB the DerivedA instance.
I think I'm understanding your question.
In main you would have your object that holds the data you want passed around. Have a derivedA public data object (or you can make it private and set it with a set function) and make derivedA.data = main's data. Then when derivedA does its stuff, the object in main will still point to it. Then you repeat the process by handing the data to derivedB with derivedB.data = main's data.
If you make char* structBuf; protected instead of private then all derived classes can access it. As it stands I'm not sure how you'll implement the process function in your derived classes.
It sounds like you're looking for some cache or data-store of already processed information. You could write a class to store this type specific info and then retrieve it in later calls to your virtual process functions. Something like:
class DataCache {
public:
void store( DerivedA* data );
void store( DerivedB* data );
std::list<DerivedA*>& getDerivedA();
std::list<DerivedB*>& getDerivedB();
}
Now your process function should take a reference to a DataCache object, so each call can store and get appropriately. DerivedB might implement process like:
DerivedB::process( DataCache& cache ) {
std::list<DerivedA*>& a_data = cache.getDerivedA();
//do something
cache.store( this );
}
I've interpreted your question as pertaining to reading in a file or stream which has a header section that sets out the subsequent instance definition sections.
#include <iostream>
class AbstractDataProcessor;
class ProcessorFactory
{
public:
static AbstractDataProcessor* create(const char id);
};
class AbstractDataProcessor
{
public:
AbstractDataProcessor() : next_(0) {}
virtual ~AbstractDataProcessor()
{
if(next_ != 0)
{
delete next_;
next_ = 0;
}
}
void process(const char* buf, int size)
{
process(buf, 0, size);
}
protected:
virtual int do_process(const char* buf, int start, int size) = 0;
void append(AbstractDataProcessor* chain)
{
if(next_ == 0)
{
next_ = chain;
}
else
{
next_->append(chain);
}
}
private:
void process(const char* buf, int start, int size)
{
int next_start = do_process(buf, start, size);
std::cout << "AbstractDataProcessor::process: start = " << start << " : size = " << size << " : next_start = " << next_start << std::endl;
if(next_ == 0 || next_start >= size)
{
return;
}
next_->process(buf, next_start, size);
}
AbstractDataProcessor* next_;
};
class HeaderProcessor : public AbstractDataProcessor
{
protected:
static const char header_sentinel = 'H';
virtual int do_process(const char* buf, int start, int size)
{
int current = start;
while(current < size && buf[current] != header_sentinel)
{
std::cout << "HeaderProcessor::do_process: buf[" << current << "] = " << buf[current] << std::endl;
AbstractDataProcessor* section_processor = ProcessorFactory::create(buf[current]);
if(section_processor != 0)
{
append(section_processor);
}
++current;
}
return current + 1;
}
};
class ElementProcessor : public AbstractDataProcessor
{
protected:
int do_process(const char* buf, int start, int size)
{
foo_ = static_cast<float>(buf[start]);
std::cout << "ElementProcessor::do_process: buf[" << start << "] = " << buf[start] << " : foo_ = " << foo_ << std::endl;
return start + (sizeof(float) / sizeof(char));
}
private:
float foo_;
};
AbstractDataProcessor* ProcessorFactory::create(char id)
{
std::cout << "ProcessorFactory::create: id = " << id << std::endl;
switch(id)
{
case 'h':
return new HeaderProcessor;
case 'e':
return new ElementProcessor;
default:
return 0;
}
}
int main(int argc, char** argv)
{
static const int buf_size = 6;
char testbuf[buf_size] = { 'e', 'H', 'x', '3', 't', '[' };
AbstractDataProcessor* testprocessor = ProcessorFactory::create('h');
testprocessor->process(testbuf, buf_size);
return 0;
}
its not the most elegant example, but it illustrates the idea of generating a linked list of processors that act on a single input stream of data. Each processor is capable of appending a new processor as appropriate, you could define another method "AbstractDataProcessor::insert" to allow for implementing a recursive delegation approach within each "do_process" method too. i haven't included any useful extraction methods, but it should be easy enough to walk the linked list and spit out pointers to something in main or wherever you need it.
You could do something like this:
class DerivedA;
class Base{
public:
virtual void Process();
protected:
static std::vector<DerivedA*> dependencies;
};
class DerivedA : public Base {
private:
char* structBuf;
public:
DerivedA() {
dependencies.push_back(this);
}
virtual void Process();
};
class DerivedB : public Base {
private:
char* structBuf;
public:
virtual void Process();
};
int main()
{
std::vector<Base*> allBase;
for(int i = 0 ; i < 10; i++) {
allBase.push_back(FactoryObject());
}
for(int i = 0 ; i < 10; i++) {
allBase[i]->Process();
}
return 0;
}
In short, while the objects are constructed the DerivedA ones are registering themselves in a static vector in Base, which means they are accessible in DerivedB once you are calling Process() on DerivedB types.
You must allow for all derived classes to be created before you can call Process. So, first map and create all and then map again and call Process(). This is of course not optimal since the base knows some about its inherited classes, but you insisted on having this factory pattern.
A better solution is to lift out the static vector from Base and store DerivedA elsewhere. But in the end it will boil down to you having to store DerivedA instances somewhere, and that registration should be done at construction, i.e. in the constructor of DerivedA. I dont know if a simple vector will do as registration, please modify this to suit your needs. For example you might want to look up DerivedA* with some identifier and need a hash or map instead.
Here comes dynamic_cast handy for you. If you have a Base* pointer, you try to do dynamic_cast. If it really is, then the result will be the DerivedA object. Else it is not DerivedA, returns NULL.
So in your main(),
Base* a = FactoryObject();
DerivedA *CheckObj= dynamic_cast<DerivedA*>(a);
DerivedA *AObj = NULL;
if(CheckObj)
{
AObj = CheckObj;
AObj->Process();
}
else
{
if(AObj)
{
AObj->Process();
CheckObj->Process();
}
}