title: Pointer Wrapper: dereference operator
body: <p>I'm pretty new to C++ and as an exercise (and perhaps eventually .Net utility) I'm doing a pointer wrapper (actually in C++/CLI, but this applies to C++ as well). This pointer wrapper (called <code>Apont</code>) currently behaves just like a pointer would, as the test below can show, if lines marked <strong>1.</strong> and <strong>2.</strong> are commented out:</p>
  
  <pre><code>int main(array&lt;System::String ^&gt; ^args)
  {
      double ia = 10; double ip = 10;
      double *p = &amp;ip;                // pointer analogy
      Apont&lt;double&gt; ^a =
          gcnew Apont&lt;double&gt;(ia);    // equivalent to what's below, without errors
      a = ~ia;/* 1.       IntelliSense: expression must have integral or unscoped enum type
                          error C2440: '=' : cannot convert from 'double' to 'Utilidades::ComNativos::Apont&lt;T&gt; ^'
                          error C2171: '~' : illegal on operands of type 'double'*/
      Console::WriteLine("ip = {0}; *p = {1}; ia = {2}; !a = {3}", ip, *p, ia, !a);
      ia = 20; ip = 20;
      Console::WriteLine("ip = {0}; *p = {1}; ia = {2}; !a = {3}", ip, *p, ia, !a);
      *p = 30;        // pointer analogy
      a-&gt;Valor = 30;  // does exacly what's below, without errors
      !a = 30;/* 2.   IntelliSense: expression must be a modifiable lvalue
                      error C2106: '=' : left operand must be l-value */
      Console::WriteLine("ip = {0}; *p = {1}; ia = {2}; !a = {3}", ip, *p, ia, !a);
      //a-&gt;Dispose();
      Console::ReadKey();
      p = nullptr;
      return 0;
  }
  </code></pre>
  
  <p>There are two things I don't like here, marked with <strong>1.</strong> and <strong>2.</strong> in the code comments, before the lines with errors. The <code>operator~</code> (see <strong>1.</strong>) is defined outside <code>Apont</code>, below:</p>
  
  <pre><code>template&lt;typename T&gt; static Apont&lt;T&gt;^% operator ~(T&amp; valor)
  {
      return gcnew Apont&lt;T&gt;(valor);
  }
  </code></pre>
  
  <p>I think this one has to be defined outside <code>Apont</code>, but I'm not sure. I cannot understand very well the errors it produces (these are, of course, in the use, not in the definition).</p>
  
  <p>To set the value to which the instance of <code>Apont</code> refers I must use a property (the line marked <strong>2.</strong> doesn't work, with errors in the setting usage only), <code>Apont::Valor</code>, which is the equivalent to use <code>*p</code>. What I'd like to do is as I use <code>*p</code> to get <strong>or set</strong> the value it points to, use <code>!a</code> with the same effect on <code>Apont</code>. Here's <code>Apont::operator!()</code>'s current definition:</p>
  
  <pre><code>T operator !()
  {
      return Valor;
  }
  </code></pre>
  
  <p>As you can see in <strong>2.</strong> (comment in the code, before the respective errors), it doesn't work for setting a value. Maybe I should return a reference? Make another operator with the same name, perhaps outside the class? I tried several options, however, I got similar errors, and came out more confused.</p>
  
  <p>The question is: how can I make an operator that behaves like <code>&amp;</code> (in this case, <code>~</code>) and one that behaves like <code>*</code> (in this case, <code>!</code>, for dereference, but that behaves like <code>Apont::Valor</code>, whose old definition you can see below)?</p>
  
  <pre><code>property T Valor
  {
      T get()
      {
          if (pointer != nullptr)             
              return *pointer;
          else if (eliminado &amp;&amp; ErroSeEliminado) // means "disposed &amp;&amp; ErrorIfDisposed"
              throw gcnew ObjectDisposedException("O objeto já foi pelo menos parcialmente eliminadao.");
          else if (ErroSeNulo) // means "ErrorIfNull"
              throw gcnew NullReferenceException();
          else
              return 0;
  // don't worry, this is not default behavior, it is returned only if you want to ignore all errors and if the pointer is null
      }
      void set(T valor)
      {
          *pointer = valor;
      }
  }
  </code></pre>