¿Cómo puedo inicializar las variables miembro de objeto C ++ en el constructor?

Tengo una clase que tiene un par de objetos como variables miembro. No quiero que se invoquen los constructores para los objetos cuando se declaran, por lo que bash colgar un puntero al objeto de forma explícita. No tengo ni idea de lo que estoy haciendo. o_O

En stackoverflow, parece ser capaz de encontrar otros ejemplos de variables miembro de objeto, pero generalmente el constructor se llama inmediatamente, así:

class MyClass { public: MyClass(int n); private: AnotherClass another(100); // this constructs AnotherClass right away! }; 

Pero quiero que el constructor MyClass llame al constructor AnotherClass. Así es como se ve mi código:

BigMommaClass.h

 #include "ThingOne.h" #include "ThingTwo.h" class BigMommaClass { public: BigMommaClass(int numba1, int numba2); private: ThingOne* ThingOne; ThingTwo* ThingTwo; }; 

BigMommaClass.cpp

 #include "BigMommaClass.h" BigMommaClass::BigMommaClass(int numba1, int numba2) { this->ThingOne = ThingOne(100); this->ThingTwo = ThingTwo(numba1, numba2); } 

Este es el error que obtengo cuando bash comstackr:

 g++ -Wall -c -Iclasses -o objects/BigMommaClass.o classes/BigMommaClass.cpp In file included from classes/BigMommaClass.cpp:1:0: classes/BigMommaClass.h:12:8: error: declaration of âThingTwo* BigMommaClass::ThingTwoâ classes/ThingTwo.h:1:11: error: changes meaning of âThingTwoâ from âclass ThingTwoâ classes/BigMommaClass.cpp: In constructor âBigMommaClass::BigMommaClass(int, int)â: classes/BigMommaClass.cpp:4:30: error: cannot convert âThingOneâ to âThingOne*â in assignment classes/BigMommaClass.cpp:5:37: error: â((BigMommaClass*)this)->BigMommaClass::ThingTwoâ cannot be used as a function make: *** [BigMommaClass.o] Error 1 

¿Estoy usando el enfoque correcto pero la syntax incorrecta? ¿O debería llegar a esto desde una dirección diferente?

Puede especificar cómo inicializar miembros en la lista de inicializadores de miembros:

 BigMommaClass { BigMommaClass(int, int); private: ThingOne thingOne; ThingTwo thingTwo; }; BigMommaClass::BigMommaClass(int numba1, int numba2) : thingOne(numba1 + numba2), thingTwo(numba1, numba2) {} 

Está intentando crear un ThingOne utilizando operator= que no va a funcionar (syntax incorrecta). Además, está utilizando un nombre de clase como nombre de variable, es decir, ThingOne* ThingOne . En primer lugar, arreglemos los nombres de las variables:

 private: ThingOne* t1; ThingTwo* t2; 

Como estos son indicadores, deben señalar algo. Si el objeto aún no se ha construido, deberá hacerlo explícitamente con new en su constructor BigMommaClass :

 BigMommaClass::BigMommaClass(int n1, int n2) { t1 = new ThingOne(100); t2 = new ThingTwo(n1, n2); } 

Generalmente, las listas de inicializadores son preferidas para la construcción, por lo que se verá así:

 BigMommaClass::BigMommaClass(int n1, int n2) : t1(new ThingOne(100)), t2(new ThingTwo(n1, n2)) { } 

Esta pregunta es un poco antigua, pero aquí hay otra forma en c ++ 11 de “hacer más trabajo” en el constructor antes de inicializar las variables de miembro:

 BigMommaClass::BigMommaClass(int numba1, int numba2) : thingOne([](int n1, int n2){return n1+n2;}(numba1,numba2), thingTwo(numba1, numba2) {} 

La función lambda anterior se invocará y el resultado pasará al constructor thingOnes. Por supuesto, puede hacer que la lambda sea tan compleja como desee.

Sé que esto es 5 años después, pero las respuestas anteriores no abordan lo que estaba mal con su software. (Bueno, lo de Yuushi, pero no me di cuenta hasta que escribí esto, ¡do!). Responden la pregunta en el título ¿Cómo puedo inicializar las variables miembro de objeto C ++ en el constructor? Esta es la otra pregunta: ¿estoy usando el enfoque correcto pero la syntax incorrecta? ¿O debería llegar a esto desde una dirección diferente?

El estilo de progtwigción es en gran medida una cuestión de opinión, pero una visión alternativa para hacer todo lo posible en un constructor es mantener a los constructores al mínimo, a menudo con una función de inicialización separada. No hay necesidad de tratar de meter toda la inicialización en un constructor, sin importar tratar de forzar cosas a veces en la lista de inicialización de constructores.

Entonces, al punto, ¿qué estaba mal con su software?

 private: ThingOne* ThingOne; ThingTwo* ThingTwo; 

Tenga en cuenta que después de estas líneas, ThingOne (y ThingTwo ) ahora tienen dos significados, según el contexto.

Fuera de BigMommaClass, ThingOne es la clase que creaste con #include "ThingOne.h"

Dentro de BigMommaClass, ThingOne es un puntero.

Eso supone que el comstackdor puede incluso dar sentido a las líneas y no se queda atascado en un ciclo pensando que ThingOne es un puntero a algo que a su vez es un puntero a algo que es un puntero a …

Más tarde, cuando escribes

 this->ThingOne = ThingOne(100); this->ThingTwo = ThingTwo(numba1, numba2); 

tenga en cuenta que dentro de BigMommaClass su ThingOne es un puntero.

Si cambia las declaraciones de los punteros para incluir un prefijo (p)

 private: ThingOne* pThingOne; ThingTwo* pThingTwo; 

Entonces ThingOne siempre se referirá a la clase y pThingOne al puntero.

Entonces es posible reescribir

 this->ThingOne = ThingOne(100); this->ThingTwo = ThingTwo(numba1, numba2); 

como

 pThingOne = new ThingOne(100); pThingTwo = new ThingTwo(numba1, numba2); 

que corrige dos problemas: el problema de doble significado y el new faltante. (¡Puedes dejar this-> si quieres!) Con eso en su lugar, puedo agregar las siguientes líneas a un progtwig mío c ++ y se comstack muy bien.

 class ThingOne{public:ThingOne(int n){};}; class ThingTwo{public:ThingTwo(int x, int y){};}; class BigMommaClass { public: BigMommaClass(int numba1, int numba2); private: ThingOne* pThingOne; ThingTwo* pThingTwo; }; BigMommaClass::BigMommaClass(int numba1, int numba2) { pThingOne = new ThingOne(numba1 + numba2); pThingTwo = new ThingTwo(numba1, numba2); }; 

Cuando escribiste

 this->ThingOne = ThingOne(100); this->ThingTwo = ThingTwo(numba1, numba2); 

el uso de this-> le dice al comstackdor que el lado izquierdo ThingOne está destinado a significar el puntero. Sin embargo, estamos dentro de BigMommaClass en ese momento y no es necesario. El problema está en el lado derecho de los iguales, donde ThingOne pretende significar la clase. Entonces, otra forma de rectificar tus problemas habría sido escribir

 this->ThingOne = new ::ThingOne(100); this->ThingTwo = new ::ThingTwo(numba1, numba2); 

o simplemente

 ThingOne = new ::ThingOne(100); ThingTwo = new ::ThingTwo(numba1, numba2); 

using :: para cambiar la interpretación del comstackdor del identificador.