473,387 Members | 1,693 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Vector Of auto ptr of class help (Please!)

reb
I more or less inherited some code that makes liberal use of STL, among
other things. Up to now I've sort of considered templates a kind of
black art, but I'm coming around to see how they can be useful. I'd
really like them if I could figure out this one problem. I'm porting
this code from Mac CodeWarrior to XCode which is using GCC 4.0.
CodeWarrior apparently rolled their own version of STL, where the
vector class contents are quite different than the gnu version.

I'll make this as abbreviated as possible. We have a record (actually,
many records, but this is just an example) like:

class CHelpMe : public CRefCnt
{
// usual ctors, dtor, methods. Nothing fancy here;
};

Base class CRefCnt does what it implies:

class CRefCnt
{
public:
virtual int AddRef() { return IncrementRefCnt(); }
virtual int Release() { return DecrementRefCnt();}

virtual ~CR180XmlDbRefCnt() { assert( 0 == m_iRefCnt );}
protected:
CR180XmlDbRefCnt() : m_iRefCnt( 1) {;}
virtual int IncrementRefCnt() { return ++m_iRefCnt;}
virtual int DecrementRefCnt() { int cRefs= --m_iRefCnt; if( cRefs ==
0) delete this; return cRefs;};
private:
int m_iRefCnt;

};

We also have an auto ptr class (condensed somewhat for posting):

template <class T>
class CAutoPtr
{
public:
CAutoPtr() : p( NULL) {;};
CAutoPtr(T* lp, bool bIsStrongRef= false) { if ((((p = lp) != NULL))
&& ! bIsStrongRef) p->AddRef();}
CAutoPtr(const CAutoPtr<T>& lp) { if ((p = lp.p) != NULL) p->AddRef();
}
~CAutoPtr() { if (p) p->Release(); p= NULL;}

void Release() { if( NULL == p) return; p->Release();p = NULL; }

_NoAddRefReleaseOnCAutoPtr<T>* operator->() const { return
(_NoAddRefReleaseOnCAutoPtr<T>*)p;}

operator T*() const { return p; }
T& operator*() const { assert( NULL != p ); return *p;}
T** operator&() { assert (NULL == p); return &p;}
T* operator=(T* lp) { if( p == lp) return p; if( p) p->Release(); p=
lp; if(p) p->AddRef(); return p;}
const CAutoPtr<T>& operator=(const CAutoPtr<T>& rhs) { if( p == rhs.p)
return *this; if( p) p->Release(); p= rhs.p; if( p) p->AddRef(); return
*this;}
bool operator==(T* pT) const { return p == pT;}
void Attach(T* p2) { if (p) p->Release(); p = p2; }
T* Detach() { T* pt = p; p = NULL;return pt;}

T* p;
};

Finally, we have a couple of typedefs:

typedef CAutoPtr<CHelpMe> CHelpMePtr;
typedef std::vector<CHelpMePtr> CHelpMePtrVector;

The problem comes when compiling when we get this error on the vector
typedef line:
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_construct.h:174:
error: no matching function for call to
'std::allocator<CHelpMePtr>::destroy(CHelpMe**)'
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/new_allocator.h:107:
note: candidates are: void __gnu_cxx::new_allocator<_Tp>::destroy(_Tp*)
[with _Tp = CHelpMePtr]

My limited knowledge of STL sees this as the compiler thinking that
CAutoPtr of CHelpMe is too ambiguous for the standard allocator class.
I've tried any number of ways to resolve this, without complete
success. Note that this same code compiles and runs fine under VC++
6.0.

Any ideas? Thanks!

Nov 3 '05 #1
4 2225
re*@mac.com wrote:
I more or less inherited some code that makes liberal use of STL, among
other things. Up to now I've sort of considered templates a kind of
black art, but I'm coming around to see how they can be useful. I'd
really like them if I could figure out this one problem. I'm porting
this code from Mac CodeWarrior to XCode which is using GCC 4.0.
CodeWarrior apparently rolled their own version of STL, where the
vector class contents are quite different than the gnu version.

I'll make this as abbreviated as possible. We have a record (actually,
many records, but this is just an example) like:

class CHelpMe : public CRefCnt
{
// usual ctors, dtor, methods. Nothing fancy here;
};

Base class CRefCnt does what it implies:

class CRefCnt
{
public:
virtual int AddRef() { return IncrementRefCnt(); }
virtual int Release() { return DecrementRefCnt();}

virtual ~CR180XmlDbRefCnt() { assert( 0 == m_iRefCnt );}
protected:
CR180XmlDbRefCnt() : m_iRefCnt( 1) {;}
virtual int IncrementRefCnt() { return ++m_iRefCnt;}
virtual int DecrementRefCnt() { int cRefs= --m_iRefCnt; if( cRefs ==
0) delete this; return cRefs;};
private:
int m_iRefCnt;

};

We also have an auto ptr class (condensed somewhat for posting):

template <class T>
class CAutoPtr
{
public:
CAutoPtr() : p( NULL) {;};
CAutoPtr(T* lp, bool bIsStrongRef= false) { if ((((p = lp) != NULL))
&& ! bIsStrongRef) p->AddRef();}
CAutoPtr(const CAutoPtr<T>& lp) { if ((p = lp.p) != NULL) p->AddRef();
}
~CAutoPtr() { if (p) p->Release(); p= NULL;}

void Release() { if( NULL == p) return; p->Release();p = NULL; }

_NoAddRefReleaseOnCAutoPtr<T>* operator->() const { return
(_NoAddRefReleaseOnCAutoPtr<T>*)p;}

operator T*() const { return p; }
T& operator*() const { assert( NULL != p ); return *p;}
T** operator&() { assert (NULL == p); return &p;}
T* operator=(T* lp) { if( p == lp) return p; if( p) p->Release(); p=
lp; if(p) p->AddRef(); return p;}
const CAutoPtr<T>& operator=(const CAutoPtr<T>& rhs) { if( p == rhs.p)
return *this; if( p) p->Release(); p= rhs.p; if( p) p->AddRef(); return
*this;}
bool operator==(T* pT) const { return p == pT;}
void Attach(T* p2) { if (p) p->Release(); p = p2; }
T* Detach() { T* pt = p; p = NULL;return pt;}

T* p;
};

Finally, we have a couple of typedefs:

typedef CAutoPtr<CHelpMe> CHelpMePtr;
typedef std::vector<CHelpMePtr> CHelpMePtrVector;

The problem comes when compiling when we get this error on the vector
typedef line:
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_construct.h:174:
error: no matching function for call to
'std::allocator<CHelpMePtr>::destroy(CHelpMe**)'
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/new_allocator.h:107:
note: candidates are: void __gnu_cxx::new_allocator<_Tp>::destroy(_Tp*)
[with _Tp = CHelpMePtr]

My limited knowledge of STL sees this as the compiler thinking that
CAutoPtr of CHelpMe is too ambiguous for the standard allocator class.
I've tried any number of ways to resolve this, without complete
success. Note that this same code compiles and runs fine under VC++
6.0.

Any ideas? Thanks!


I tried this code:

#include <vector>
#include <cassert>

class CRefCnt
{
public:
virtual int AddRef() { return IncrementRefCnt(); }
virtual int Release() { return DecrementRefCnt();}
virtual ~CRefCnt() { assert( 0 == m_iRefCnt );}
protected:
CRefCnt() : m_iRefCnt( 1) {;}
virtual int IncrementRefCnt() { return ++m_iRefCnt;}
virtual int DecrementRefCnt() { int cRefs= --m_iRefCnt; if(
cRefs == 0) delete this; return cRefs;};
private:
int m_iRefCnt;
};

template <class T>
class CAutoPtr
{
public:
CAutoPtr() : p( NULL) {;};
CAutoPtr(T* lp, bool bIsStrongRef= false) { if ((((p = lp) !=
NULL)) && ! bIsStrongRef) p->AddRef();}
CAutoPtr(const CAutoPtr<T>& lp) { if ((p = lp.p) != NULL)
p->AddRef(); }
~CAutoPtr() { if (p) p->Release(); p= NULL;}
void Release() { if( NULL == p) return; p->Release();p = NULL;
}
//_NoAddRefReleaseOnCAutoPtr<T>* operator->() const { return
(_NoAddRefReleaseOnCAutoPtr<T>*)p;}
operator T*() const { return p; }
T& operator*() const { assert( NULL != p ); return *p;}
T** operator&() { assert (NULL == p); return &p;}
T* operator=(T* lp) { if( p == lp) return p; if( p)
p->Release(); p=lp; if(p) p->AddRef(); return p;}
const CAutoPtr<T>& operator=(const CAutoPtr<T>& rhs) { if( p ==
rhs.p) return *this; if( p) p->Release(); p= rhs.p; if( p) p->AddRef();
return *this;}
bool operator==(T* pT) const { return p == pT;}
void Attach(T* p2) { if (p) p->Release(); p = p2; }
T* Detach() { T* pt = p; p = NULL;return pt;}
T* p;
};

class CHelpMe : public CRefCnt {};

typedef CAutoPtr<CHelpMe> CHelpMePtr;
typedef std::vector<CHelpMePtr> CHelpMePtrVector;

int main()
{
CHelpMePtrVector v( 10 );
return 0;
}

with g++ 3.4.1, VC++ 6 (sp6 and all STL patches applied from
dinkumware.com), Comeau online
(http://www.comeaucomputing.com/tryitout/), and dinkumware online
(using EDG and Microsoft .NET 2003). All compiled it fine. Note that I
had to make some additional changes to your code, and in particular I
deleted the -> operator in CAutoPtr because I don't have the
_NoAddRefReleaseOnCAutoPtr<> class.

Can you post a minimal but complete sample that demonstrates the
problem?

Cheers! --M

Nov 3 '05 #2
reb
Thanks for checking that out. I also took your code, changed it
slightly and built it as a separate project. It appears to be a gcc 4.0
vs. gcc 3.x thing. I could compile successfully under 3.3.
Unfortuately, I need to use 4.0 (required to get it to run on Intel
Macs). Here's the current version:

#include <vector>
#include <cassert>

template <class T>
class _NoAddRefReleaseOnCAutoPtr : public T
{
private:
virtual int AddRef()=0;
virtual int Release()=0;
};

class CRefCnt
{
public:
virtual int AddRef() { return IncrementRefCnt();}
virtual int Release() { return DecrementRefCnt();}
virtual ~CRefCnt() { assert( 0 == m_iRefCnt );}
protected:
CRefCnt() : m_iRefCnt( 1) {;}
virtual int IncrementRefCnt() { return ++m_iRefCnt;}
virtual int DecrementRefCnt() { int cRefs= --m_iRefCnt;
if(cRefs == 0) delete this; return cRefs;};
private:
int m_iRefCnt;

};

template <class T>
class CAutoPtr
{
public:
CAutoPtr() : p( NULL) {;};
CAutoPtr(T* lp, bool bIsStrongRef= false) { if ((((p = lp) !=
NULL)) && ! bIsStrongRef) p->AddRef();}
CAutoPtr(const CAutoPtr<T>& lp) { if ((p = lp.p) != NULL)
p->AddRef(); }
~CAutoPtr() { if (p) p->Release(); p= NULL;}

void Release() { if( NULL == p) return; p->Release();p = NULL;
}

_NoAddRefReleaseOnCAutoPtr<T>* operator->() const { return
(_NoAddRefReleaseOnCAutoPtr<T>*)p;}
operator T*() const { return p; }
T& operator*() const { assert( NULL != p ); return *p;}
T** operator&() { assert (NULL == p); return &p;}
T* operator=(T* lp) { if( p == lp) return p; if( p)
p->Release(); p=lp; if(p) p->AddRef(); return p;}
const CAutoPtr<T>& operator=(const CAutoPtr<T>& rhs) { if( p ==
rhs.p) return *this; if( p) p->Release(); p= rhs.p; if( p) p->AddRef();
return *this;}
bool operator==(T* pT) const { return p == pT;}

void Attach(T* p2) { if (p) p->Release(); p = p2; }
T* Detach() { T* pt = p; p = NULL;return pt;}
T* p;
};

class CHelpMe : public CRefCnt {};

typedef CAutoPtr<CHelpMe> CHelpMePtr;
typedef std::vector<CHelpMePtr> CHelpMePtrVector;

int main()
{
CHelpMePtrVector v( 10 );
return 0;
}
And here's the compiler output:

/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_construct.h:
In function 'void std::_Destroy(_ForwardIterator, _ForwardIterator,
_Allocator) [with _ForwardIterator = CHelpMePtr*, _Allocator =
std::allocator<CHelpMePtr>]':
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_vector.h:273:
instantiated from 'std::vector<_Tp, _Alloc>::~vector() [with _Tp =
CHelpMePtr, _Alloc = std::allocator<CHelpMePtr>]'
/Users/reb/test1/main.cpp:71: instantiated from here
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_construct.h:174:
error: no matching function for call to
'std::allocator<CHelpMePtr>::destroy(CHelpMe**)'
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/new_allocator.h:107:
note: candidates are: void __gnu_cxx::new_allocator<_Tp>::destroy(_Tp*)
[with _Tp = CHelpMePtr]

In playing with the code some more, if I comment the CAutoPtr
operator&, I still get a compiler error, but it's quite different:

/usr/bin/ld:
/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/libgcc_eh.a(unwind-dw2.o)
has external relocation entries in non-writable section (__TEXT,__text)
for symbols:
restFP
saveFP
collect2: ld returned 1 exit status

Any idea what might be ticking off the 4.0 compiler? If not, any
suggestions for where I might find an answer? Thanks again. -R

Nov 3 '05 #3
re*@mac.com wrote:
Thanks for checking that out. I also took your code, changed it
slightly and built it as a separate project. It appears to be a gcc 4.0
vs. gcc 3.x thing. I could compile successfully under 3.3.
Unfortuately, I need to use 4.0 (required to get it to run on Intel
Macs). Here's the current version:

#include <vector>
#include <cassert>

template <class T>
class _NoAddRefReleaseOnCAutoPtr : public T
{
private:
virtual int AddRef()=0;
virtual int Release()=0;
};

class CRefCnt
{
public:
virtual int AddRef() { return IncrementRefCnt();}
virtual int Release() { return DecrementRefCnt();}
virtual ~CRefCnt() { assert( 0 == m_iRefCnt );}
protected:
CRefCnt() : m_iRefCnt( 1) {;}
virtual int IncrementRefCnt() { return ++m_iRefCnt;}
virtual int DecrementRefCnt() { int cRefs= --m_iRefCnt;
if(cRefs == 0) delete this; return cRefs;};
private:
int m_iRefCnt;

};

template <class T>
class CAutoPtr
{
public:
CAutoPtr() : p( NULL) {;};
CAutoPtr(T* lp, bool bIsStrongRef= false) { if ((((p = lp) !=
NULL)) && ! bIsStrongRef) p->AddRef();}
CAutoPtr(const CAutoPtr<T>& lp) { if ((p = lp.p) != NULL)
p->AddRef(); }
~CAutoPtr() { if (p) p->Release(); p= NULL;}

void Release() { if( NULL == p) return; p->Release();p = NULL;
}

_NoAddRefReleaseOnCAutoPtr<T>* operator->() const { return
(_NoAddRefReleaseOnCAutoPtr<T>*)p;}
operator T*() const { return p; }
T& operator*() const { assert( NULL != p ); return *p;}
T** operator&() { assert (NULL == p); return &p;}
T* operator=(T* lp) { if( p == lp) return p; if( p)
p->Release(); p=lp; if(p) p->AddRef(); return p;}
const CAutoPtr<T>& operator=(const CAutoPtr<T>& rhs) { if( p ==
rhs.p) return *this; if( p) p->Release(); p= rhs.p; if( p) p->AddRef();
return *this;}
bool operator==(T* pT) const { return p == pT;}

void Attach(T* p2) { if (p) p->Release(); p = p2; }
T* Detach() { T* pt = p; p = NULL;return pt;}
T* p;
};

class CHelpMe : public CRefCnt {};

typedef CAutoPtr<CHelpMe> CHelpMePtr;
typedef std::vector<CHelpMePtr> CHelpMePtrVector;

int main()
{
CHelpMePtrVector v( 10 );
return 0;
}
And here's the compiler output:

/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_construct.h:
In function 'void std::_Destroy(_ForwardIterator, _ForwardIterator,
_Allocator) [with _ForwardIterator = CHelpMePtr*, _Allocator =
std::allocator<CHelpMePtr>]':
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_vector.h:273:
instantiated from 'std::vector<_Tp, _Alloc>::~vector() [with _Tp =
CHelpMePtr, _Alloc = std::allocator<CHelpMePtr>]'
/Users/reb/test1/main.cpp:71: instantiated from here
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_construct.h:174:
error: no matching function for call to
'std::allocator<CHelpMePtr>::destroy(CHelpMe**)'
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/ext/new_allocator.h:107:
note: candidates are: void __gnu_cxx::new_allocator<_Tp>::destroy(_Tp*)
[with _Tp = CHelpMePtr]

In playing with the code some more, if I comment the CAutoPtr
operator&, I still get a compiler error, but it's quite different:

/usr/bin/ld:
/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/libgcc_eh.a(unwind-dw2.o)
has external relocation entries in non-writable section (__TEXT,__text)
for symbols:
restFP
saveFP
collect2: ld returned 1 exit status

Any idea what might be ticking off the 4.0 compiler? If not, any
suggestions for where I might find an answer? Thanks again. -R


Hmm, since this seems to be GNU-specific, I'd suggest you post on the
gnu.g++.* newsgroups. They should have more expertise in this area.
Alternately, you could try a different STL implementation such as
STLport (http://www.stlport.com/).

In any case, it does seem that the operator& overload is likely the
culprit of your first set of problems. I'm not sure about the second
set, but it looks related to exception handling.

Cheers! --M

Nov 3 '05 #4
reb
Thanks for your help and advice. I'm checking gnu, etc. next. Cheers!

Nov 4 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Dark Knight | last post by:
Hello, I am working on a program to get use to the vector.h Templete class. Program: #include <string> #include <iostream> #include <fstream> #include <vector>
4
by: csx | last post by:
Hi all, I have the following code, which at the moment is a vector of arrays. But unfortunately, it doesnt do what I want. Basically, here is an example in Java that I want to work in C++. var...
6
by: Ash Lux | last post by:
Does the C++ vector template class use pointer-based link lists? Could I get a link explaining how it works, regardless of what it uses? Thank You, Ash Lux
7
by: Frank Bormann | last post by:
Hi guys, I'm a C++ beginner. I was wondering if there is a generalized vector base class, through which I could pass a pointer to any kind of vector to a function, regardless of what type of...
2
by: Matthias Kaeppler | last post by:
Hi, I'm holding a vector of boost::filesystem::pathS and a vector of pointers to them. I use the reserve member function on both to reserve space for 500 files. That means, for the 501th file...
18
by: sd2004 | last post by:
could someone please show/help me to copy all element from "class dog" to "class new_dog" ? Note: "class new_dog" has new element "age" which should have value "my_age"...
12
by: y-man | last post by:
Hi, I am creating a child class of the vector, which contains a couple of functions to make the work with carthesian coordinate vectors easier. To make things work more easily, I would like to...
2
by: Disc B | last post by:
Hi, My program has a class and has a vector as the member. This is vector of the class itself. But during compilation it throws error that class is undefined and cannot be used. Below is my code...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.