Objetos y copiadores creados sin RVO en C ++

Soy nuevo en C ++. Considere el siguiente código:

class foo 
{ 
 int f; 

 public: 
   foo(int f1=0) : f(f1) { 
   cout<<"In conversion ctor\n"; 
 } 

foo(const foo & rhs) : f(rhs.f) 
{ 
    cout<<" In copy ctor\n"; 
} 

 foo& operator=(const foo & that) 
{ 
    f=that.f; 
    cout<<"In = optor\n"; 
    return *this; 
} 

}; 

 foo rbv() 
  { 
    foo obj(9); 
    return obj;                        //named return by value [def. 1] 
  } 

   foo caller() 
   { 
      return rbv();              // return by value [def. 2] 
   } 

int main(void) 
{ 
   foo box=caller(); 
   return 0; 
 }
  1. ¿Son correctas las definiciones de RBV y NRBV como se indica en los comentarios?
  2. ¿Es obligatorio tener definido un ctor de copia accesible aunque no se llame durante RVO?
  3. Sin RVO, en los bloques de código

       foo rbv() 
        { 
         foo obj(9); 
         return obj; 
        } 
    
        foo ret= rbv();
    

¿Son correctos los siguientes pasos en la creación de 'ret'?

(1) se crea un temporal (digamos obj_temp) usando copy ctor from obj, se destruye el objeto de pila 'obj',

(2) ret es una copia construida a partir de obj_temp, obj_temp destruida más tarde;

lo que implica que hay tres objetos, 'obj', 'obj_temp' y 'ret' y dos copiadores involucrados.

preguntado el 16 de mayo de 11 a las 19:05

¿Qué texto ves cuando lo ejecutas? ¿Confirma tu conjetura? -

Si es nuevo en C ++, tiene muchas más cosas que deberían preocuparle más que RVO. La mayoría (probablemente el 90% o más) de las clases no deberían poder copiarse en absoluto. -

def. 1 es NRVO, def. 2 es RVO, falta una 'O' y algunos errores tipográficos en la P.1. @dlev Sin optimización y considerando solo NRVO y llamando a rbv () en lugar de caller (), se llaman 1 ctor de conversión, 2 ctors de copia. Esto confirma mi suposición. Con la optimización, solo se llama a la conversión ctor. -

@Neil Butterworth, De alguna manera me interesé en RVO. -

2 Respuestas

  1. Me parece bien.
  2. Debe tener definido un constructor de copia accesible si va a copiar objetos. Incluso si la copia se puede optimizar.
  3. Eso me suena bien, aunque el orden preciso podría estar definido por la implementación. Usted tendría que

contestado el 17 de mayo de 11 a las 00:05

¿Son correctas las definiciones de RBV y NRBV como se indica en los comentarios?

Son RVO y NRVO (Optimización del valor de retorno y Optimización del valor de retorno con nombre)

¿Es obligatorio tener definido un ctor de copia accesible aunque no se llame durante RVO?

Es obligatorio, el compilador tiene que verificar que los constructores sean accesibles, si no lo son, el compilador debe desencadenar un error y fallar al compilar.

Sin RVO, en los bloques de código

foo rbv() { 
  foo obj(9); 
  return obj; 
} 
foo ret = rbv();

El código, tal como está, requeriría las siguientes operaciones: Constructor tomando un int dentro foo crear obj. Copie la construcción en la declaración de devolución a la devolución temporal $tmp1, copia la construcción de ret en el lugar de llamada del temporal. Ahora, el compilador puede eludir las dos copias colocando el valor de retorno (de acuerdo con la convención de llamadas) encima de ret, asi que $tmp1 y ret son la misma ubicación de memoria, y al construir obj en la parte superior de la misma ubicación de memoria, por lo que al final los tres objetos pueden ser un solo objeto y no es necesario realizar copias.

contestado el 17 de mayo de 11 a las 00:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.