sobrecarga qué que objeto herencia ejemplos definicion copia constructores clases c++

qué - que es un destructor en c++



¿Inicializando las variables de miembro usando el mismo nombre para los argumentos de constructor que para las variables de miembro permitidas por el estándar de C++? (3)

Me pregunto qué dice el estándar C ++ al respecto. ¿Es legal y garantizado para trabajar siempre?

Sí. Eso es perfectamente legal. Completamente estándar conforme.

Blah(std::vector<int> vec): vec(vec){} ^ ^ | | | this is the argument to the constructor this is your member data

Como solicitó la referencia en el Estándar, aquí está, con un ejemplo.

§12.6.2 / 7

Los nombres en la lista de expresiones de un inicializador de mem se evalúan en el ámbito del constructor para el que se especifica el inicializador de mem.

[Example: class X { int a; int b; int i; int j; public: const int& r; X(int i): r(a), b(i), i(i), j(this->i) {} //^^^^ note this (added by Nawaz) };

inicializa X :: r para referirse a X :: a, inicializa X :: b con el valor del parámetro constructor i, inicializa X :: i con el valor del parámetro constructor i, e inicializa X :: j con el valor de X :: i; esto ocurre cada vez que se crea un objeto de la clase X. ]

[Nota: debido a que el inicializador de mem se evalúa en el alcance del constructor, este puntero se puede usar en la lista de expresiones de un inicializador de mem para referirse al objeto que se está inicializando. ]

Como puede ver, hay otra cosa interesante a tener en cuenta en el ejemplo anterior, y el comentario del propio Estándar.

Por cierto, como nota al margen, ¿por qué no acepta el parámetro como referencia constante ? :

Blah(const std::vector<int> & vec): vec(vec) {} ^^^^const ^reference

Evita la copia innecesaria del objeto vectorial original.

Me di cuenta de que es posible inicializar las variables miembro con un argumento de constructor con el mismo nombre que se muestra en el siguiente ejemplo.

#include <cstdio> #include <vector> class Blah { std::vector<int> vec; public: Blah(std::vector<int> vec): vec(vec) {} void printVec() { for(unsigned int i=0; i<vec.size(); i++) printf("%i ", vec.at(i)); printf("/n"); } }; int main() { std::vector<int> myVector(3); myVector.at(0) = 1; myVector.at(1) = 2; myVector.at(2) = 3; Blah blah(myVector); blah.printVec(); return 0; }

g ++ 4.4 con los argumentos -Wall -Wextra -pedantic no avisa y funciona correctamente. También funciona con clang ++. Me pregunto qué dice el estándar C ++ al respecto. ¿Es legal y garantizado para trabajar siempre?


Como otros ya han respondido: Sí, esto es legal. Y sí, esto está garantizado por el estándar para trabajar.

Y me parece horrible cada vez que lo veo, forzándome a hacer una pausa: "¿ vec(vec) ? ¿WTF? Ah, sí, vec es una variable miembro ..."

Esta es una de las razones por las que a muchos, incluido yo mismo, les gusta usar una convención de nomenclatura que deja en claro que una variable miembro es una variable miembro. Las convenciones que he visto incluyen agregar un sufijo de subrayado ( vec_ ) o un prefijo m_ ( m_vec ). Luego, el inicializador lee: vec_(vec) / m_vec(vec) , que es una obviedad.


Está garantizado siempre para trabajar (lo uso bastante a menudo). El compilador sabe que la lista de inicializadores tiene la forma: member(value) y, por lo tanto, sabe que el primer vec in vec(vec) debe ser un miembro. Ahora en el argumento para inicializar el miembro, se pueden usar ambos, los argumentos al constructor y otros símbolos, como en cualquier expresión que esté presente dentro del constructor. En este punto, aplica las reglas de búsqueda regulares, y el argumento vec oculta el miembro vec .

La sección 12.6.2 de la norma trata de la inicialización y explica el proceso con el párrafo 2 que trata la búsqueda del miembro y el párrafo 7 con la búsqueda del argumento.

Los nombres en la lista de expresiones de un inicializador de mem se evalúan en el ámbito del constructor para el que se especifica el inicializador de mem. [Ejemplo:

class X { int a; int b; int i; int j; public: const int& r; X(int i): r(a), b(i), i(i), j(this->i) {} };