¿Cómo creo un objeto de clase en C++?

7 minutos de lectura

Avatar de usuario de Kathick
Kathick

Tengo un fondo de Java. En Java creamos un objeto de clase como este.

Example example = new Example();

La clase Ejemplo puede tener constructor o no puede tener constructor.

Puedo usar lo mismo en C++ como este

Example* example = new Example();

Donde el constructor es obligatorio.

De este tutorial Tengo que podemos crear un objeto como este:

Example example;

Que no requieren un constructor.

Tengo dos preguntas.

  1. ¿Cuál es la diferencia entre ambas formas de crear objetos de clase?

  2. Si estoy creando un objeto como Example example; ¿Cómo uso eso en una clase singleton?

como suelo hacer así.

Sample* Singleton::get_sample() {
    if (sample == NULL) {
        sample = new Sample();
    }
    return sample;
}

Avatar de usuario de Andy Prowl
Andy merodea

Puedo usar lo mismo en c ++ como este […] Donde el constructor es obligatorio. De este tutorial Tengo que podemos crear un objeto como este […] Que no requieren un constructor.

Esto está mal. un constructor debe existir para crear un objeto. el constructor podría ser definido implícitamente por el compilador bajo algunas condiciones si no proporciona ninguna, pero eventualmente el constructor debe estar allí si desea que se cree una instancia de un objeto. De hecho, la vida útil de un objeto está definida para comenzar cuando regresa la rutina del constructor.

Del Párrafo 3.8/1 del Estándar C++11:

[…] La vida útil de un objeto de tipo T comienza cuando:

— se obtiene un almacenamiento con la alineación y el tamaño apropiados para el tipo T, y

— si el objeto tiene una inicialización no trivial, su inicialización está completa.

Por lo tanto, un constructor debe estar presente.

1) ¿Cuál es la diferencia entre ambas formas de crear objetos de clase?

Cuando instancias un objeto con duración de almacenamiento automático, como este (donde X es alguna clase):

X x;

Está creando un objeto que se destruirá automáticamente cuando salga del alcance. Por otro lado, cuando lo haces:

X* x = new X();

Está creando un objeto dinámicamente y está vinculando su dirección a un puntero. De esta manera, el objeto que creaste no ser destruido cuando tu x puntero sale del alcance.

En Modern C++, esto se considera una práctica de programación dudosa: aunque los punteros son importantes porque permiten realizar semántica de referencia, crudo los punteros son malos porque podrían provocar fugas de memoria (objetos que sobreviven a todos sus punteros y nunca se destruyen) o punteros colgantes (punteros que sobreviven al objeto al que apuntan, lo que podría causar un Comportamiento indefinido cuando se elimina la referencia).

De hecho, al crear un objeto con newsiempre tengo que recordar destruirlo con delete:

delete x;

Si necesita semántica de referencia y se ve obligado a usar punteros, en C++ 11 debería considerar usar punteros inteligentes en cambio:

std::shared_ptr<X> x = std::make_shared<X>();

Los punteros inteligentes se encargan de los problemas de administración de la memoria, que es lo que le da dolor de cabeza con los punteros sin procesar. Los punteros inteligentes son, de hecho, casi lo mismo que las referencias a objetos de Java o C#. El “casi” es necesario porque el programador debe cuidarse de no introducir dependencias cíclicas al poseer punteros inteligentes.

2) Si estoy creando un objeto como Ejemplo de ejemplo; cómo usar eso en una clase singleton.

Podrías hacer algo como esto (código simplificado):

struct Example
{
    static Example& instance()
    {
        static Example example;
        return example;
    }

 private:

    Example() { }
    Example(Example const&) = delete;
    Example(Example&&) = delete;
    Example& operator = (Example const&) = delete;
    Example& operator = (Example&&) = delete;

};

  • Cabe señalar que se llama al constructor vacío incluso cuando la expresión no tiene llaves.

    – jiggunjer

    3 de julio de 2015 a las 7:22

Example example;

Esta es una declaración de una variable llamada example de tipo Example. Esto inicializará por defecto el objeto, lo que implica llamar a su constructor predeterminado. El objeto tendrá una duración de almacenamiento automático, lo que significa que se destruirá cuando salga del alcance.

Example* example;

Esta es una declaración de una variable llamada example el cual es un puntero a una Example. En este caso, la inicialización predeterminada lo deja sin inicializar: el puntero no apunta a ninguna parte en particular. No hay Example objeto aquí. El objeto puntero tiene una duración de almacenamiento automático.

Example* example = new Example();

Esta es una declaración de una variable llamada example el cual es un puntero a una Example. Este objeto puntero, como el anterior, tiene una duración de almacenamiento automático. Luego se inicializa con el resultado de new Example();. Este new expresión crea un Example objeto con duración de almacenamiento dinámico y luego le devuelve un puntero. Entonces el example el puntero ahora apunta a ese objeto asignado dinámicamente. El Example El objeto se inicializa con valor, lo que llamará a un constructor proporcionado por el usuario si hay uno o, de lo contrario, inicializará todos los miembros en 0.

Example* example = new Example;

Esto es similar a la línea anterior. La diferencia es que el Example el objeto se inicializa por defecto, lo que llamará al constructor predeterminado de Example (o déjelo sin inicializar si no es de tipo clase).

Un objeto asignado dinámicamente debe ser deleted (probablemente con delete example;).

Hay dos formas de hacer/crear objetos en C++.

El primero es:

MyClass myclass; // if you don;t need to call rather than default constructor    
MyClass myclass(12); // if you need to call constructor with parameters

El segundo es:

MyClass *myclass = new MyClass();// if you don;t need to call rather than default constructor
MyClass *myclass = new MyClass(12);// if you need to call constructor with parameters

En c ++, si usa una nueva palabra clave, el objeto se almacenará en el montón. es muy útil si está utilizando este objeto durante mucho tiempo y si usa el primer método, se almacenará en la pila. se puede utilizar sólo un período de tiempo corto. Aviso: si usa una nueva palabra clave, recuerde que devolverá un valor de puntero. debe declarar el nombre con *. Si usa el segundo método, no elimina el objeto en el montón. debe eliminar usted mismo usando la palabra clave eliminar;

delete myclass;

Example example;

Aquí el ejemplo es un objeto en la pila.

Example* example=new Example();

Esto podría dividirse en:

Example* example;
....
example=new Example();

Aquí la primera declaración crea un ejemplo de variable que es un “puntero a Ejemplo”. Cuando se llama al constructor, se le asigna memoria en el montón (asignación dinámica). Es responsabilidad del programador liberar esta memoria cuando ya no se necesita. (C++ no tiene recolección de basura como Java).

Avatar de usuario de Miguel Prz
miguel prz

1) ¿Cuál es la diferencia entre ambas formas de crear objetos de clase?

a) puntero

Example* example=new Example();
// you get a pointer, and when you finish it use, you have to delete it:

delete example;

b) Declaración simple

Example example;

obtienes una variable, no un puntero, y se destruirá fuera del alcance que se declaró.

2) Singleton C++

Esta pregunta SO puede ayudarte

avatar de usuario de felixgaal
felixgaal

En primer lugar, ambos casos llaman a un constructor. Si tú escribes

Example *example = new Example();

entonces estás creando un objeto, llama al constructor y recupera un puntero a ella.

Si tú escribes

Example example;

La única diferencia es que obtienes el objeto y no un puntero a ello. El constructor llamado en este caso es el mismo que el anterior, el constructor predeterminado (sin argumento).

En cuanto a la pregunta singleton, simplemente debe invocar su método estático escribiendo:

Example *e = Singleton::getExample();

1) ¿Cuál es la diferencia entre ambas formas de crear objetos de clase?

El primero es un puntero a un objeto construido en el montón (por new). El segundo es un objeto que se construyó implícitamente. (Constructor predeterminado)

2) Si estoy creando un objeto como Ejemplo de ejemplo; cómo usar eso en una clase singleton.

Depende de tus objetivos, lo más fácil es ponerlo simplemente como miembro de una clase.

Una muestra de una clase singleton que tiene un objeto de Example clase:

class Sample
{

    Example example;

public:

    static inline Sample *getInstance()
    {
        if (!uniqeInstance)
        {
            uniqeInstance = new Sample;
        }
        return uniqeInstance;
    }
private:
    Sample();
    virtual ~Sample();
    Sample(const Sample&);
    Sample &operator=(const Sample &);
    static Sample *uniqeInstance;
};

¿Ha sido útil esta solución?