aMule Forum
English => Compilation problems => Topic started by: Stu Redman on December 27, 2010, 10:16:49 PM
-
The following compiles and runs fine with MSVC:
Index: ScopedPtr.h
===================================================================
--- ScopedPtr.h (revision 10416)
+++ ScopedPtr.h (working copy)
@@ -26,6 +26,7 @@
#ifndef SCOPEDPTR_H
#define SCOPEDPTR_H
+#include "OtherFunctions.h" // Needed for DeleteContents()
/**
* CScopedPtr is a simple smart pointer.
@@ -68,7 +69,7 @@
return ptr;
}
-private:
+protected:
//@{
//! A scoped pointer is neither copyable, nor assignable.
CScopedPtr(const CScopedPtr<TYPE>&);
@@ -132,5 +133,25 @@
TYPE* m_ptr;
};
+
+template <typename STL_CONTAINER>
+class CScopedContainer : public CScopedPtr<STL_CONTAINER>
+{
+
+public:
+ /** Constructor. Note that CScopedContainer takes ownership of the array. */
+ CScopedContainer(STL_CONTAINER* ptr = 0)
+ : CScopedPtr(ptr)
+ {}
+
+ ~CScopedContainer()
+ {
+ if (m_ptr) {
+ DeleteContents(*m_ptr);
+ }
+ // m_ptr itself is deleted in base class
+ }
+};
+
#endif // SCOPEDPTR_H
// File_checked_for_headers
but GCC barfs at it:
In file included from ../../../../trunk/src/utils/fileview/../../SafeFile.cpp:29:0:
../../../../trunk/src/utils/fileview/../../ScopedPtr.h: In constructor ‘CScopedContainer<STL_CONTAINER>::CScopedContainer(STL_CONTAINER*)’:
../../../../trunk/src/utils/fileview/../../ScopedPtr.h:144:5: error: class ‘CScopedContainer<STL_CONTAINER>’ does not have any field named ‘CScopedPtr’
../../../../trunk/src/utils/fileview/../../ScopedPtr.h: In destructor ‘CScopedContainer<STL_CONTAINER>::~CScopedContainer()’:
../../../../trunk/src/utils/fileview/../../ScopedPtr.h:149:7: error: ‘m_ptr’ was not declared in this scope
make[4]: *** [mulefileview-SafeFile.o] Error 1
Is it just me or is this more complicated?
-
Yes, it's a bit more complicated.
In file included from ../../../../trunk/src/utils/fileview/../../SafeFile.cpp:29:0:
../../../../trunk/src/utils/fileview/../../ScopedPtr.h: In constructor ‘CScopedContainer<STL_CONTAINER>::CScopedContainer(STL_CONTAINER*)’:
../../../../trunk/src/utils/fileview/../../ScopedPtr.h:144:5: error: class ‘CScopedContainer<STL_CONTAINER>’ does not have any field named ‘CScopedPtr’
‘CScopedPtr’ and ‘CScopedPtr<STL_CONTAINER>’ are different classes names, and since we're deriving from the second, the first is unknown to the compiler. Just consider, that you're allowed to derive from both ‘CScopedPtr<A>’ and ‘CScopedPtr<B>’. Then which one should ‘CScopedPtr’ refer?
../../../../trunk/src/utils/fileview/../../ScopedPtr.h: In destructor ‘CScopedContainer<STL_CONTAINER>::~CScopedContainer()’:
../../../../trunk/src/utils/fileview/../../ScopedPtr.h:149:7: error: ‘m_ptr’ was not declared in this scope
Regarding templates, the compiler binds unqualified names at parse time instead of instatiation time (and does it right according to the C++ standard). Since ‘m_ptr’ is an unqualified name in this context, it tries to bind it when parsing the template. But since it is defined in the base class (which itself is also a template), the name is not yet known. You have to qualify the name with either ‘this->’ or ‘CScopedPtr<STL_CONTAINER>::’ to make the name binding happen at instantiation time.
To fix these issues:
diff --git a/src/ScopedPtr.h b/src/ScopedPtr.h
index d1fdab2..b3ae431 100644
--- a/src/ScopedPtr.h
+++ b/src/ScopedPtr.h
@@ -141,13 +141,13 @@ class CScopedContainer : public CScopedPtr<STL_CONTAINER>
public:
/** Constructor. Note that CScopedContainer takes ownership of the array. */
CScopedContainer(STL_CONTAINER* ptr = 0)
- : CScopedPtr(ptr)
+ : CScopedPtr<STL_CONTAINER>(ptr)
{}
~CScopedContainer()
{
- if (m_ptr) {
- DeleteContents(*m_ptr);
+ if (this->m_ptr) {
+ DeleteContents(*(this->m_ptr));
}
// m_ptr itself is deleted in base class
}
-
Thank you, very well explained!
Strange though how MSVC implements kind of a different C++...