Mapped functors to member functions losing scope - c++

I'd like to be able to call some member functions from different classes which all have the same general syntax and base class. Something along the lines of
class A: public BaseClass
{
public:
A();
~A();
int DoFoo();
int DoBar();
int DoBarBar();
};
class B : public BaseClass
{
public:
B();
~B();
int DoSomething();
int DoSomethingElse();
int DoAnother();
};
Where I could potentially places the member functions from both classes into one map so that I could have something like
key value
"Option1" *DoFoo()
"Option2" *DoSomething()
"Option3" *DoFoo()
... ...
"Option6" *DoAnother()
Where I could call a function to return a value based on what option I chose, regardless of what class the function belongs to.
Through some searching, I tried to implement my own mapped set of functors. However, the map retains the address of the functor, but the functions within become null.
Here are my functor declarations which store a class object and a function pointer
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
//////////////////////////////////////////////////////////////
//Functor Classes
//////////////////////////////////////////////////////////////
class TFunctor
{
public:
virtual void operator()()=0; // call using operator
virtual int Call()=0; // call using function
};
// derived template class
template <class TClass> class TSpecificFunctor : public TFunctor
{
private:
int (TClass::*fpt)(); // pointer to member function
TClass* pt2Object; // pointer to object
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
TSpecificFunctor(TClass* _pt2Object, int(TClass::*_fpt)())
{ pt2Object = _pt2Object; fpt=_fpt; };
// override operator "()"
virtual void operator()()
{ (*pt2Object.*fpt)();}; // execute member function
// override function "Call"
virtual int Call()
{return (*pt2Object.*fpt)();}; // execute member function
};
typedef std::map<std::string, TFunctor*> TestMap;
//////////////////////////////////////////////////////////////
//Test Classes
//////////////////////////////////////////////////////////////
//Base Test class
class base
{
public:
base(int length, int width){m_length = length; m_width = width;}
virtual ~base(){}
int area(){return m_length*m_width;}
int m_length;
int m_width;
};
//Inherited class which contains two functions I would like to point to
class inherit:public base
{
public:
inherit(int length, int width, int height);
~inherit();
int volume(){return base::area()*m_height;}
int area2(){return m_width*m_height;}
int m_height;
TestMap m_map;
};
where my inherit class constructor looks like:
inherit::inherit(int length, int width, int height):base(length, width)
{
m_height = height;
TSpecificFunctor<inherit> funcA(this, &inherit::volume);
m_map["a"] = &funcA;
TSpecificFunctor<inherit> funcB(this, &inherit::area2);
m_map["b"] = &funcB;
}
Which is where I am mapping two functions into a map. Things still look okay in the above function in terms of memory address and function pointers.
I then try to create an instance of inherit in a new class...
class overall
{
public:
overall();
~overall(){}
inherit *m_inherit;
TestMap m_mapOverall;
};
overall::overall()
{
m_inherit = new inherit(3,4,5);
TestMap tempMap = m_inherit->m_map;
int i = 0;
}
Here when I look at the values of m_inherit->m_map, I notice that the keys are still consistent, however the memory addresses of the functions which I tried to point to have disappeared.
I haven't had much experience with functors but from my understanding, it is able to retain states, which I assume means that I can call member functions outside of its class. But I'm starting to think that my member functions disappear because it is out of scope.

You are right, it is a scooping issue. In the inherit constructor, funcA and funcB are both allocated on the stack and destroyed once the function goes out of scope. The leaves m_map with stale pointers.
What you really want is something like
inherit::inherit(int lenght, int width, int height) :base(length, width)
{
m_height = height;
// allocated on the heap
TSpecificFunctor<inherit> * funcA = new TSpecificFunctor<inherit>(this, &inherit::volume);
m_map["a"] = funcA;
// allocated on the heap
TSpecificFunctor<inherit> * funcB = new TSpecificFunctor<inherit>(this, &inherit::area2);
m_map["b"] = funcB;
} // when this function exits funcA and funcB are not destroyed
But, to avoid any memory leaks, the destructor for inherit will need to clean up the values
inherit::~inherit()
{
for(TestMap::iterator it = m_map.begin(); it != m_map.end(); ++it) {
delete it->second;
}
}
Using new and delete can easily lead to memory leaks. To prevent them, I would suggest looking into smart points like std::unique_ptr and std::shared_ptr. Also, functors are becoming obsolete with the introduction of lambdas in C++11. They are really neat and worth looking into if you are not familiar with them.
If your compiler supports them, to do this with lambdas
#include <functional>
// ...
typedef std::map<std::string, std::function<int(void)>> TestMap;
// ...
inherit::inherit(int length, int width, int height):base(length, width)
{
m_height = height;
m_map["a"] = [this]() -> int { return volume(); };
m_map["b"] = [this]() -> int { return area2(); };
// can be called like so
m_map["a"]();
m_map["b"]();
}
// No need to clean up in destructors

You're right - the TSpecificFunctors go out of scope at the end of inherit's constructor, so you shouldn't keep pointers to them.
If you can, prefer smart pointers, e.g.
#include <memory>
...
typedef std::map<std::string, std::shared_ptr<TFunctor>> TestMap;
...
inherit::inherit(int length, int width, int height):base(length, width)
{
m_height = height;
m_map["a"] = std::shared_ptr<TSpecificFunctor<inherit>>(
new TSpecificFunctor<inherit>(this, &inherit::volume));
m_map["b"] = std::shared_ptr<TSpecificFunctor<inherit>>(
new TSpecificFunctor<inherit>(this, &inherit::area2));
}
Your main concern then is to ensure that the functors in m_inherit->m_map are not invoked after m_inherit is destroyed or you will get undefined behaviour. In this case, you're safe since you leak m_inherit (it's never destroyed).

Related

Manage abstract classes in std container

After a lot of research I still don't understand how to deal with an abstract class collection with smart pointers.
Here are the errors I got:
error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Shape; _Dp = std::default_delete<Shape>]'
base_ptr s = shapes.front();
error: no matching function for call to 'std::unique_ptr<Shape>::unique_ptr(Shape&)'
shapes.push(base_ptr(b));
By compiling the minimal code to replicate the error (code online avaiable).
#include <queue>
#include <memory>
class Shape {
public:
virtual int getPerimeter() =0;
};
typedef std::unique_ptr<Shape> base_ptr;
class Circle : public Shape {
public:
virtual int getPerimeter() { return 1; };
};
class Square : public Shape {
public:
virtual int getPerimeter() { return 0; };
};
class ShapeManager {
public:
ShapeManager();
void useShape() {
if(shapes.empty())
throw "Work stack is empty.";
base_ptr s = shapes.front();
s->getPerimeter();
shapes.pop();
}
void submitShape(Shape &b) {
shapes.push(base_ptr(b));
}
private:
std::queue<base_ptr> shapes;
};
int main(int argc, char **argv) {
ShapeManager s();
Circle c;
s.submitShape(c);
s.useShape();
return 1;
}
It works if I declare the queue as queue<Shape*> but I don't want to deal with pointers -meaning *.
EDIT, this code compiles. Thanks everyone. This article suggested by Guillaume Racicot helps seeing clearer the situation.
#include <queue>
#include <memory>
class Shape {
public:
virtual int getPerimeter() =0;
};
typedef std::unique_ptr<Shape> base_ptr;
class Circle : public Shape {
public:
Circle() {};
virtual int getPerimeter() { return 1; };
};
class Square : public Shape {
public:
virtual int getPerimeter() { return 0; };
};
class ShapeManager {
public:
ShapeManager();
void useShape() {
if(shapes.empty())
throw "Work stack is empty.";
base_ptr s = std::move(shapes.front());
s->getPerimeter();
shapes.pop();
}
void submitShape(base_ptr b) {
shapes.push(std::move(b));
}
private:
std::queue<base_ptr> shapes;
};
int main(int argc, char **argv) {
ShapeManager s;
base_ptr c = std::make_unique<Circle>();
s.submitShape(std::move(c));
s.useShape();
return 1;
}
The container is a distraction. The problem is that unique_ptr is not copyable; if it were, it wouldn't be unique. So you probably need to add a call to std::move:
base_ptr s = std::move(shapes.front());
This means something different from what the original code might have been intended to do; it removes the object from the container. If that's not what you wanted, then std::move isn't the right answer and, probably, unique_ptr is not the right mechanism.
There are many problems in your example, not just misuse of smart pointers. First, the most obvious once is your declaration of s:
ShapeManager s();
This declares a function named s that returns a ShapeManager and takes no parameter.
Maybe you meant to declare an object of type ShapeManager?
ShapeManager s{};
// Or
ShapeManager s;
Secondly, you are misusing smart pointer. You have a queue of unique pointer. A unique pointer is a RAII wrapper around a free store allocated object. That means that it's a wrapper that is constructed with an object allocated with new. In your example, you're not doing that. You are constructing unique pointer with an object that has automatic storage.
A smart pointer that points to a automatic storage allocated object is the observer pointer: is must not own, delete or try to manage anything about that object. In fact, observer pointer is a language feature instead of a library one. It's commonly called a pointer.
This is your code with usage of observer pointers:
template<typename T>
using observer_ptr = T*;
struct ShapeManager {
void useShape() {
if(shapes.empty())
throw "Work stack is empty.";
auto s = shapes.front();
s->getPerimeter();
shapes.pop();
}
void submitShape(Shape &b) {
shapes.push(&b);
}
private:
std::queue<base_ptr> shapes;
};
int main() {
ShapeManager s;
Circle c; // Automatic storage
Rectangle r; // Automatic storage too.
s.submitShape(c);
s.submitShape(r);
s.useShape();
}
However, you might not want to hold them using automatic storage. My guess is you want to use std::unique_ptr everywhere instead. This allow the object submitted to the shape manager to outlive it's scope. For that you'll need to allocate objects on the free store. The most common way is to use std::make_unique:
struct ShapeManager {
void useShape() {
if(shapes.empty())
throw "Work stack is empty.";
// We must create a reference,
// Using simply auto would require copy,
// Which is prohibited by unique pointers
auto&& s = shapes.front();
s->getPerimeter();
shapes.pop();
}
void submitShape(base_ptr b) {
shapes.push(std::move(b));
}
private:
std::queue<base_ptr> shapes;
};
int main() {
ShapeManager s;
// Allocated on the free store,
// The lifetime of c and r are managed by
// The unique pointer.
auto c = std::make_unique<Circle>();
auto r = std::make_unique<Rectangle>();
s.submitShape(std::move(c));
s.submitShape(std::move(r));
s.useShape();
}

How to use inherited objects in parent class functions?

I have two classes: MovableObject and GravitySource that inherited from MovableObject (because GravitySources can move too). At MovableObject I have function integrate that calculates movement params using list of GravitySources.
So, I can't put list of GravitySources into this function. And I don't want to create duplicates of MovableObject functions (including integrate) in GravitySource. So, how to solve this problem? It is C++.
Your MovableObject::integrate function declaration can take a MovableObject* pointer as a parameter, something like:
return_type MovableObject::integrate(Movable* );
In this way, you can pass GravitySources to the Movable::integrate, and the behaviour will be polymorphic, i.e. you have access to virtual functions via the pointer to base MovableObject*. Therefore make sure you have some common virtual functions that can be called via the pointer to base, and delegate the work to them.
If you want to pass an array of GravitySources, then it's a bit more tricky, since you cannot safely use a MovableObject* pointer to move through a GravitySources array. What you can do though is to forward-declare the class GravitySources, then you can declare
return_type MovableObject::integrate(GravitySources* );
You can use incomplete types via pointers, so the above declaration is OK. Just make sure the implementation of the function comes after the full definition of GravitySources. You can now pass arrays of GravitySources to your function!
Some toy example below:
#include <iostream>
class GravitySources; // need this forward declaration
class MovableObject
{
public:
void integrate(GravitySources* gs, std::size_t N); // process N GravitySources
virtual void f(); // our common virtual interface
virtual ~MovableObject() = default;
};
class GravitySources: public MovableObject
{
int _label; // label the instance
public:
GravitySources(int label): _label(label) {}
void f() override;
};
void MovableObject::integrate(GravitySources* gs, std::size_t N)
{
// process the GravitySources
for (std::size_t i = 0; i < N; ++i)
{
gs[i].f();
}
}
void MovableObject::f()
{
std::cout << "MovableObject::f()" << std::endl;
}
void GravitySources::f()
{
std::cout << "GravitySources::f() " << _label << std::endl;
}
int main()
{
MovableObject mo;
GravitySources gs[3] {1, 2, 3}; // 3 GravitySources
mo.integrate(gs, 3); // process them
}

Is it possible to store polymorphic class in shared memory?

Suppose I have class Base and Derived : public Base.
I have constructed a shared memory segment using boost::interprocess library. Is it possible to have code similar to this:
Base* b = new Derived();
write(b); //one app writes
Base* b2 = read(b); //second app reads
//b equals b2 (bitwise, not the ptr location)
The problems I see here is for instance that the required space for a derived class of Base is unknown (so how much shmem to allocate?)
Q: how to pass objects via pointers between applications?
Just read its documentation
In particular:
Virtuality forbidden
The virtual table pointer and the virtual table are in the address
space of the process that constructs the object, so if we place a
class with a virtual function or virtual base class, the virtual
pointer placed in shared memory will be invalid for other processes
and they will crash.
This problem is very difficult to solve, since each process needs a
different virtual table pointer and the object that contains that
pointer is shared across many processes. Even if we map the mapped
region in the same address in every process, the virtual table can be
in a different address in every process. To enable virtual functions
for objects shared between processes, deep compiler changes are needed
and virtual functions would suffer a performance hit. That's why
Boost.Interprocess does not have any plan to support virtual function
and virtual inheritance in mapped regions shared between processes.
Shared memory originally only allows POD structures (at heart, they may have constructors/copy/etc...).
Boost.Interprocess raises the bar by emulating pointers semantics on top of offsets into the shared memory segment.
However, a virtual pointer is not a pointer to pure data, it's a pointer to code sections, and that is where things get complicated because code sections are not necessarily mapped to the same address from one process to another (even if they were launched from the same binary).
So... no, virtual pointers-polymorphic objects cannot be stored in shared memory.
However, just because many C++ implementations chose to use a virtual-pointer mechanism does not mean that this is the only way to have polymorphic behavior. For example, in LLVM and Clang they build on their closed hierarchies to get polymorphism without virtual pointers (and RTTI) so as to lower memory requirements. Those objects could, effectively, be stored in shared memory.
So, how to get polymorphism compatible with shared memory: we need not to store pointers to tables/functions, however we can store indexes.
Example of the idea, but could probably be refined.
/// In header
#include <cassert>
#include <vector>
template <class, size_t> class BaseT;
class Base {
template <class, size_t> friend class BaseT;
public:
int get() const; // -> Implement: 'int getImpl() const' in Derived
void set(int i); // = 0 -> Implement: 'void setImpl(int i)' in Derived
private:
struct VTable {
typedef int (*Getter)(void const*);
typedef void (*Setter)(void*, int);
VTable(): _get(0), _set(0) {}
Getter _get;
Setter _set;
};
static std::vector<VTable>& VT(); // defined in .cpp
explicit Base(size_t v): _v(v) {}
size_t _v;
}; // class Base
template <class Derived, size_t Index>
class BaseT: public Base {
public:
BaseT(): Base(Index) {
static bool const _ = Register();
(void)_;
}
// Provide default implementation of getImpl
int getImpl() const { return 0; }
// No default implementation setImpl
private:
static int Get(void const* b) {
Derived const* d = static_cast<Derived const*>(b);
return d->getImpl();
}
static void Set(void* b, int i) {
Derived* d = static_cast<Derived*>(b);
d->setImpl(i);
}
static bool Register() {
typedef Base::VTable VTable;
std::vector<VTable>& vt = Base::VT();
if (vt.size() <= Index) {
vt.insert(vt.end(), Index - vt.size() + 1, VTable());
} else {
assert(vt[Index]._get == 0 && "Already registered VTable!");
}
vt[Index]._get = &Get;
vt[Index]._set = &Set;
}
}; // class BaseT
/// In source
std::vector<VTable>& Base::VT() {
static std::vector<VTable> V;
return V;
} // Base::VT
int Base::get() const {
return VT()[_v]._get(this);
} // Base::get
void Base::set(int i) {
return VT()[_v]._set(this, i);
} // Base::set
Okay... I guess that now you appreciate the compiler's magic...
Regarding the usage, it's fortunately much simpler:
/// Another header
#include <Base.h>
// 4 must be unique within the hierarchy
class Derived: public BaseT<Derived, 4> {
template <class, size_t> friend class BaseT;
public:
Derived(): _i(0) {}
private:
int getImpl() const { return _i; }
void setImpl(int i) { _i = i; }
int _i;
}; // class Derived
In action at ideone.
I believe you are looking at serialization of objects. Have a look at http://www.boost.org/doc/libs/1_51_0/libs/serialization/doc/index.html
A few ways you can do is:
1. serialize your C++ class
2. send data to another app
3. deserialize into C++ class.
//From the example above , I have removed VTable
// I also removed static variables as per boost::interprocess
// static variable don't work with shared memory, and also I did not see
// any advantage in actually builting a VTable for all derived classes
#include <vector>
#include <boost/bind.hpp>
#include <boost/function.hpp>
template <class> class BaseT;
class Base {
template <class> friend class BaseT;
boost::function< int (void) > _get;
boost::function< void (int) > _set;
public:
int get() {
return _get();
} // -> Implement: 'int get() ' in Derived
void set(int i) {
_set(i);
} // = 0 -> Implement: 'void set(int i)' in Derived
}; // class Base
template <class Derived>
class BaseT : public Base {
public:
BaseT() : Base(), impl(static_cast<Derived *> (this)) {
Base::_get = boost::bind(&BaseT<Derived>::get, this);
Base::_set = boost::bind(&BaseT<Derived>::set, this, _1);
}
int get() {
return impl->get();
}
void set(int i) {
impl->set(i);
}
private:
Derived * impl;
};
//some A implementation of Base
struct A : BaseT<A> {
int get() {
return 101; //testing implementation
}
void set(int i) {
; //implementation goes here
}
};
//some B implementation of Base
struct B : BaseT<B> {
int get() {
return 102; //testing implementation
}
void set(int i) {
; //implementation goes here
}
};
int main() {
BaseT<A> objectA;
BaseT<B> objectB;
Base *a = &objectA;
Base *b = &objectB;
std::cout << a->get() << " returned from A class , "
<< b->get() << " returned from B class " << std::endl;
return 0;
}
//While redefining I changed semantics of constnance in getter,
//and had non- const Derived pointer used for both getter and setter.
//But original simantics can be preserved as following:
int get() const {
//return impl->get();
//this enforces that get has to be const
static_cast<const Derived *> (this)->get() ;
}

Why is virtual function not being called?

//GUITEXT
class guitext : public entity {
public:
guitext(graphics *gfx, std::string _text, float _x, float _y,
float _size, float timeToLive);
bool update(float deltaTime, gameworld *world);
void draw(graphics *gfx);
};
void guitext::draw(graphics *gfx) { printf("draw"); }
//ENTITY
class entity {
public:
virtual bool update(float deltaTime, gameworld *world)
{ return false; }
virtual void draw(graphics *gfx) { }
};
//GAMEWORLD
void gameworld::addEntity(entity e) { entitys.push_back(e); }
//MAIN
for(int i = 0; i < (int)entitys.size(); i++) { entitys[i].draw(gfx); }
I have a vector in my gameworld class. When I add push a guitext entity to this vector I expect it to call the guitext::draw() function. But the base class function is being called. What am I doing wrong?
You made a vector of entity. Those objects always have type entity. If you want to invoke polymorphism, they need to be pointers or references. How can a vector of entity store a guitext? There's not enough space, it doesn't know how to destroy it, etc etc.
Was the vector declared as vector<entity>? Then only the base class part can be stored there, i.e. you lose polymorphism (which only works through pointer or reference in C++).
What you've done is a bit concealed variant of slicing.
You should define entitys to contain pointers to entity. Slightly edited example derived from your code.
#include "stdafx.h"
#include <vector>
#include <string>
class entity
{
public:
virtual void draw() { }
};
class guitext : public entity
{
public:
void draw()
{
printf("draw");
}
};
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<entity *> entitys;
guitext g;
entitys.push_back(&g);
for(int i = 0; i < (int)entitys.size(); i++)
{
entitys[i]->draw();
}
return 0;
}
You're storing Entitys, not pointers to objects of varying derived types of Entity.
In addition, in your case it's not good idea to pass arguments by value, i suppose there will be very big quantity of objects that need to be redrawed. Better, by const reference, since functon doesn't change state of passed object inside.

C++ Nested classes driving me crazy

i am trying to compile this very simple piece of code
class myList
{
public:
std::vector<std::string> vec;
class Items
{
public:
void Add(std::string str)
{
myList::vec.push_back(str);
};
}items;
};
int main()
{
myList newList;
newList.items.Add("A");
}
what can i do to make this work without creating more objects that needed or overcomplicating stuff...
Add a couple of constructors and a pointer to the parent class.
#include <string>
#include <vector>
class myList
{
public:
std::vector<std::string> vec;
myList(): items(this) {} // Added
class Items
{
public:
Items(myList *ml): self(ml) {} // Added
void Add(std::string str)
{
self->vec.push_back(str); // Changed
};
myList *self; //Added
}items;
};
int main()
{
myList newList;
newList.items.Add("A");
}
You need the myList() constructor, so it registers instances of itself with the instance of the inner class member variable. Then you need the Items constructor to store the pointer to the outer myList class instance. Finally in the Add method, you need to reference vec in the stored myList instance.
As Catskul points out, the Item constructor mustn't actually do anything with the myList pointer it receives. I'd also like to say that though this answer is closer to the original intent, steveth45's answer is closer to what you would want to do in a real program.
This way you aren't exposing your class members directly. Your example seems over-architected a bit. Why put a std::vector into a class and then expose it as public?
class myList
{
private:
std::vector<std::string> vec;
public:
void Add(std::string str)
{
vec.push_back(str);
};
};
int main()
{
myList newList;
newList.Add("A");
}
Unlike Java, inner objects in C++ don't have access to an outer 'this' pointer ... if you think about it there may be cases where there isn't one to reference.
Richard Quirk's solution is the nearest you can get in C++
Inner classes are only related by name. You can't refer to the vector in the base class like that.
You either need to move the vector in to the inner class or store a reference to it.
While this post is a few years old I might be able to add something useful to it. While I will say that the design of the class in the original post doesn't look that great, there are times where it's useful to have an embedded class be able to access the containing class. This can easily be done without storing extra pointers. Below is an example. It should work as I took it from some existing code and changed some names around. The key is the EmbeddorOf macro. Works like a charm.
//////////////////// .h file /////////////////////////
struct IReferenceCounted
{
virtual unsigned long AddRef() = 0;
virtual unsigned long Release() = 0;
};
struct IFoo : public IReferenceCounted
{
};
class Foo : public IFoo
{
public:
static IFoo* Create();
static IFoo* Create(IReferenceCounted* outer, IReferenceCounted** inner);
private:
Foo();
Foo(IReferenceCounted* outer);
~Foo();
// IReferenceCounted
unsigned long AddRef();
unsigned long Release();
private:
struct EIReferenceCounted : IReferenceCounted
{
// IReferenceCounted
unsigned long AddRef();
unsigned long Release();
} _inner;
unsigned long _refs;
IReferenceCounted* _outer;
};
//////////////// .cpp file /////////////////
#include <stdio.h>
#include <stddef.h>
#include "Foo.h"
#define EmbeddorOf(class, member, this) \
(class *) ((char *) this - offsetof(class, member))
// Foo
Foo::Foo() : _refs(1), _outer(&this->_inner)
{
}
Foo::Foo(IReferenceCounted* outer) : _refs(1), _outer(outer)
{
}
Foo::~Foo()
{
printf("Foo::~Foo()\n");
}
IFoo* Foo::Create()
{
return new Foo();
}
IFoo* Foo::Create(IReferenceCounted* outer, IReferenceCounted** inner)
{
Foo* foo = new Foo(outer);
*inner = &foo->_inner;
return (IFoo*) foo;
}
// IReferenceCounted
unsigned long Foo::AddRef()
{
printf("Foo::AddRef()\n");
return this->_outer->AddRef();
}
unsigned long Foo::Release()
{
printf("Foo::Release()\n");
return this->_outer->Release();
}
// Inner IReferenceCounted
unsigned long Foo::EIReferenceCounted::AddRef()
{
Foo* pThis = EmbeddorOf(Foo, _inner, this);
return ++pThis->_refs;
}
unsigned long Foo::EIReferenceCounted::Release()
{
Foo* pThis = EmbeddorOf(Foo, _inner, this);
unsigned long refs = --pThis->_refs;
if (refs == 0)
{
// Artifically increment so that we won't try to destroy multiple
// times in the event that our destructor causes AddRef()'s or
// Releases().
pThis->_refs = 1;
delete pThis;
}
return refs;
}
Nick
You can simplify this by the following construct:
typedef std::vector<std::string> myList;
Really why don't you use the STL vector directly?
This way you get all the standard algorithms work with the
data.