[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 446
  • Last Modified:

Const template parameters

I have a smart pointer class (CPointer). Now I need to be able to pass back smart pointers which point to a const.
 
In other words I need to be able to model this behaviour:
 
SomeObject *get_Message() ;
const SomeObject *get_Message() ;
 
by using this kind of syntax perhaps?
CPointer<const SomeObject> get_Message() ;
 
using this:
 
const CPointer<SomeObject> get_Message() ;
 
doesn't work because that just means that the pointer can't change, not that the object within it can't change.
 
Do I have to use a template specialization for this, and if so how? Will this work?
 
template<> class CPointer<Const Element>
 
Thanks
0
SeanH
Asked:
SeanH
  • 4
  • 3
  • 2
  • +3
1 Solution
 
KangaRooCommented:
CPointer<const SomeObject>
should be fine. Just tried it with some other auto_ptr:

void f()
{
   auto_ptr<const char> ap;
   ap = new char[100];
   *ap = '\0'; // this is not allowed
}
0
 
SeanHAuthor Commented:
But this code within the class fails :

CObject *l_pObject = dynamic_cast<CObject *>(m_pElement) ;

What am I doing wrong here?
0
 
KangaRooCommented:
That is not due to the auto_ptr<const MyClass> construction I think. What is the error message the compiler gives? What is the type of m_pElement.
Based on your question, my answer was correct. So your smartpointer or the class used in it does some 'non standard' things.

We'll need to see more of your declarations.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
tdubroffCommented:
This may help I dunno:

const <type*> const ptrname;
0
 
KangaRooCommented:
>> CObject *l_pObject = dynamic_cast<CObject *>(m_pElement) ;
Is that within the smart pointer class?
0
 
basantCommented:
I don't think there is a significant meaning of returning const object. ( NOt even the pointer);

say
int foo() { return 2; }
// if you want to receive it as a const use :
const int p = foo();

If you want to return constant then it is preferable to return either a pointer or a reference.

e.g
const int& foo()
or
const int* foo()
0
 
tdubroffCommented:
Hmm perhaps you can do something like this:

const <type*> const ptr = fcnThatReturnsPtrToConst();
0
 
SeanHAuthor Commented:
Okay,

Let me explain. This may help. I am designing a class hierarchy. The base class of all objects is CObject. This is used (amoung other things) to control object lifetime.

The class hierarchy does not allow "naked" pointers. All pointers returned are smart pointers (my CPointer class). On initialization and termination the CPointer class calls functions of the CObject.

Now I could just say that all pointers point to a CObject, but this removes a great deal of type-safety. I want to be able to pass these templated CPointers back (which works) but I also need to be able to handle pointers to const objects.

However the following code needs to work as well:

if(m_pElement != 0) {
  CObject *l_pObject =
   dynamic_cast<CObject *>(m_pElement) ;
  if(l_pObject->Release() == 0) {
    delete l_pObject ;
  }
}

Unfortunately it doesn't work in a case where m_pElement is a const. I have tried const_cast of both m_pElement and the this pointer and neither allow a dynamic_cast.

What I have since tried to do is to split the logic into a specialized template class. However I still cannot get the above code to work within the class:

template <> 
class CPointer<class Element const>
{
private:
  const Element *m_pElement ;
.....
}

I'm sorry if I caused confusion by making the question vague, and so I have increased the points to 300 (as a means of apology).

Thanks
0
 
abdijCommented:
Here is a code that does what you need:

But since i could not model the project to your exact needs i get an error whenever i type to execute the following code

if(pSomeObject1!= 0) {
  CObject *l_pObject =
   dynamic_cast<CObject *>(pSomeObject1) ;
  if(l_pObject->Release() == 0) {
    delete l_pObject ;
  }
}

saying my class is not polymorphic. Hope you will not get the error when you implement my code in your project.

The code is given below

// Constants.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "afx.h"

// the some oject class whose pointer manip has to be curbed
class SomeObject
{
public:
      int            m_nAge;
      char      m_szName[40];

      SomeObject(int nAge)
      {
            m_nAge = nAge;
      }

};

// the class that has acess to the SomeOject
class Access
{
public:
      SomeObject*            m_pSomeObject;

      const SomeObject* const            getObject()
      {
            return m_pSomeObject;
      }

      Access(SomeObject* pSomeOject)
      {
            m_pSomeObject = pSomeOject;
      }

};

// the main routine
int main(int argc, char* argv[])
{
      SomeObject*            pSomeObject = new SomeObject(10); // the some ojject class
      Access*                  pAccess            = new Access(pSomeObject); // the access class

// now get the constant pointer through which you cannot modify the member vars but access them
      const SomeObject* const pSomeObject1 = pAccess->getObject();
      //pSomeObject1->nAge = 10;

      // valid use
      printf("The Age is %d\n",pSomeObject1->m_nAge);
      // invalid use
      //pSomeObject1->m_nAge = 20;

      delete pSomeObject ;
      delete pAccess      ;
      
      return 0;
}


Thax
Feel free to comment.
My mailid is abdij_b@hotmail.com
0
 
SeanHAuthor Commented:
This is the behaviour that I want to emulate with my CPointer<Element> class. Unfortunately whenever I create a CPointer<Element const> the dynamic_cast fails to work, throwing the error:

C2682: cannot use dynamic_cast to convert from 'const class CObject *' to 'class CObject *'

If I use const_cast to a intermediate object it simply fails with the error:

C2681: 'const class Element *' : invalid expression type for dynamic_cast

for the code:

CObject *l_pObject = dynamic_cast<CObject *>(const_cast<Element *>(m_pElement)) ;
0
 
SeanHAuthor Commented:
Aaaarrrggghhh!

The reason I was getting an error is that I was a dimwit, and changed only the dynamic_cast code in one place, when it is called in two!

I think abdij's answer came closest to my final solution, so if you want to send in an answer I'll accept it.

Thanks
0
 
abdijCommented:
Thanx Pal
0
 
giora1Commented:
Hi Sean and abdij,

I found your correspondence interesting, as I'm currently implementating an almost identical infrastructure, of SmartPtr and reference counting.
I might have missed something in the long answer of abdij, so I'll mention some issues which might be helpful for you, Sean:
1. Youi may use constness for the address of the pointer, e.g.:
T const * GetPtr()
{
 return (T const *)m_pInterface;
}
Or something similar. I use it in my code.
Then, the casting in the function thath uses this code would look something like
void UserFunction()
{
  T* pTemp = (T*)dynamic_cast<T const *>(GetPtr());
}
I'm not sure this is the case in your code, but I suspect it might be.

2. A by-product of your question is showing the following code:
if(m_pElement != 0) {
  CObject *l_pObject =
   dynamic_cast<CObject *>(m_pElement) ;
  if(l_pObject->Release() == 0) {
    delete l_pObject ;
  }
}
And I'd like to comment, that this is a very insecure way to handle objects' lifetime.
First - I'd locate the deletion within the Release() implementation.
Second - I'd wrap the decrement operation (as well as the increment one in the AddRef()) with a thread safe mechanism.
I still didn't tested it thoroughly, but used the simple InterlockedIncrement and InterlockedDecrement which are supported on Windows.

3. If I understood your constness problem correctly, then it is much deeper than what was answered above.
You may want to have a ConstSmartPtr, which is NOT the same as SmartPtr.
Scott Meyers, in his excellant book "More Effective C++" discusses Smart Pointers thoroughly.
Pages 179-182 are dedicated for this very issue (ConstSmartPtr), and I tend to treat it as the best place to consult with.

Hope this helps, any comments are more than welcome.

Giora
0
 
giora1Commented:
By the way, Sean, I'd love to exchange ideas with you, regarding SmartPointers and reference counting.
As it might not be interesting for other experts, I'll appreciate it if you could write me directly:
giora@radcom.co.il

Thanks,

Giora
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 4
  • 3
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now