Pregunta

Estoy empezando con C ++ y tuve algunos problemas para entender cómo funciona el alcance de las variables miembro privadas en una clase. Por favor vea el siguiente código

class Foo{
    private:
        std::vector<int> container;
    public:
        // other methods
};

int main(int argc, char* argv[])
{
    Foo* foo = new Foo;
    // other method calls to which foo is passed
    delete foo;
    return 0;
}

En el código anterior, la variable " container " es una variable miembro privada. Estoy invocando & Quot; Foo & Quot; instancia y pasarlo a varios otros métodos y clases. Las siguientes son mis dudas

  1. ¿Cuál será el alcance de la variable " container " ;? ¿Existirá esa variable hasta que elimine la instancia foo?
  2. ¿Necesito hacer el " contenedor " como un puntero al vector?

Gracias por la ayuda

¿Fue útil?

Solución

  1. Sí, la vida útil del miembro contenedor durará todo el tiempo que exista el objeto que lo contiene, hasta que llame a delete en el puntero que lo señala (foo en su caso).
  2. No, no hay razón para hacerlo. Para convertirlo en un puntero, debe crear un objeto dinámico de vector<int> del que necesitaría administrar la vida útil (incluida la eliminación de llamadas en el puntero del contenedor). Eso es innecesario aquí. Suponiendo que desea que el contenedor dure tanto como el objeto Foo, está bien que lo contenga directamente, sin hacerlo con un puntero.

Pasar el puntero <=> solo pasará el puntero. El objeto al que apunta no se copiará, solo el puntero que lo señala si es necesario. Si conoces Java, entonces te ayuda si te digo que pasar el puntero es lo mismo que pasar una referencia a un objeto en Java, por ejemplo:

Foo f = new Foo();
// just passes the reference (pointer in C++) to doIt. 
// the actual object is not copied
doIt(f);

Otros consejos

Estoy invocando " Foo " instancia

En realidad, está creando una instancia de clase Foo .

Específicamente, está asignando un bloque de memoria fuera del montón a través de new () . Este bloque de memoria es lo suficientemente grande como para contener Foo :: container y cualquier otra clase de sobrecarga que Foo requiera.

(En este ejemplo, no hay ninguno. Con otras clases, puede haber atributos adicionales o quizás una tabla de puntero virtual).

Naturalmente, new () invoca el constructor (¿quizás predeterminado?) Foo :: Foo () , que a su vez inicializa Foo :: container a través del constructor std :: vector .

¿Cuál será el alcance de la variable "container"?

container es un atributo [componente] de la instancia foo . Existe mientras exista la instancia foo .

En cuanto al alcance, podemos hablar de Foo :: container . Pero no puede acceder a Foo :: constainer sin una instancia de la clase Foo . (Por ejemplo, el objeto foo .) Foo :: constainer no existe sin una instancia de la clase Foo .

(Hay variables de clase que funcionan de manera algo diferente, donde un valor se comparte en todas las instancias. Pero ese no es el caso aquí.)

Este alcance es IRRELEVANT para su control de acceso de miembro público / protegido / privado / amigo.

Por ejemplo, en algunos Foo :: myPublicMethod () puede referirse a Foo :: container . Aunque también podría renunciar al alcance explícito en esta situación y referirse a él como contenedor .

Eso sí, siendo privado, no puede acceder a Foo :: container fuera de los métodos de clase Foo .

¿Existirá esa variable hasta que elimine la instancia foo?

Sí.

¿Necesito hacer el " contenedor " como un puntero al vector?

No. Puedes, pero ciertamente no tienes que hacerlo.

En términos generales, recomiendo que los miembros de la instancia de clase no sean punteros junto con new en el constructor y delete en el destructor. Es ineficiente y problemático. (El constructor de copia predeterminado puede copiar el valor del puntero, el destructor puede eliminar el mismo valor del puntero dos veces).


Dependiendo de sus necesidades, puede considerar:

int main(int argc, char* argv[])
{
  Foo foo;
  // other method calls to which foo is passed
  return 0;
}

foo quedaría fuera de alcance después de return 0; y se eliminaría automáticamente. Además, foo se asignaría fuera de la pila en lugar del montón.


Puede encontrar una copia usada de El Manual de referencia anotado de C ++ es útil . Es antiguo, pero tiene una alta relación señal / ruido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top