Valerio Camerini
Valerio Camerini

Reputation: 47

Shadowing variables

My question is about variables defined into classes. I show you my problem.

I have defined this class:

class Measure {

int N;
double measure_set[];
char nomefile[];
double T;

public:
    void get( );
    void printall( );
    double mean( );
    double thermal_comp( );
};

I would like method get to do the following:

  1. read numbers from a .dat file and save into measure_set array;
  2. read user input and save it into variable T;

Here is what I've done:

void Measure::get() 
{   
    cout << "Insert filename:" << endl;
    cin >> nomefile;
    cout << endl;
    cout << nomefile << endl;
    cout << endl;

    int M=0;
    int nmax=50;

    ifstream f;
    f.open(nomefile);
    while(M<nmax)
    {
        f >> measure_set[M];
        if(f.eof()) 
        break;
        M++;
    }
    f.close();
    N=M+1;

    cout << "Insert temperature:" << endl;
    cin >> T;
    cout << endl;
} 

What happens is that I've noticed that T is memorized in measure_set[0]. Why this happens and how can I write a working code? I'm not that expert in C++, using this only for computation purposes, although I could solve my problem in other ways I would like to learn how to make this work in C++. Thanks a lot!

Upvotes: 2

Views: 14813

Answers (2)

Liam de Koster-Kjaer
Liam de Koster-Kjaer

Reputation: 103

Your declarations of the Measure class's members:

double measure_set[];
char nomefile[];

Are declaring arrays without declaring the number of elements in the array. This is not legal C++, though apparently some compilers will support it.

Use std::vector if you want dynamically sized arrays, or allocate and free the array memory yourself eg.

//Declaration
double* measure_set;

//Allocation
unsigned int arrayLen = 10;
measure_set = new double[arrayLen];

//Assigning values to array elements
for(int i = 0; i < arrayLen; ++i) {
  measure_set[i] = 0;
}

//Freeing allocated memory
delete[] measure_set;

You current code:

measure_set[M];

Is referencing an array element in an array that hasn't been allocated any memory. If you pre-allocate the array memory this will be fine, as long as you are not writing past the bounds of the array.

With an std::vector (dynamically sized array) you might want to use the push_back or emplace_back functions to insert the value into the vector instead of assigning values using the square bracket operator.

Also, when using a vector, you may want to pre-allocate the underlying array as well, using the reserve function (etc.) to avoid the costly operation of resizing the vector.

Upvotes: -1

kfsone
kfsone

Reputation: 24269

In both C and C++ it is legal for the same name to be used within multiple scopes - some compilers (e.g. gcc -Wshadow) will provide a mechanism that warns you about this since it can cause confusion.

#include <iostream>

int i = 0;
int main() {
    int i = 1;
    for (int i = 0; i < 10; ++i) {
        int i = 2 * i;
        std::cout << i << std::endl;
    }
    return 0;
}

Some compilers will compile this and output '0, 2, 4, 6, 8, ...'. Some won't.

A common way to avoid this is to use prefixes. "m_" for "member", "s_" for "static", "g_" for "global", etc. Some coding styles use a "_" suffix for member variables. This also helps to keep member variables from clashing with similarly named getters/setters if that's the way your camel rolls.

class Measure {
    int         m_n;
    double      m_measureSet[MEASURE_SET_SIZE]; // [] is not legal in a class.
    std::string m_nomefile;
    double      m_t;

public:
    const std::string& nomefile() const { return m_nomefile; }
    ...
};

Where this pays off is in the usage, I tend to find developers are encouraged to use the accessors rather than the members (it seems to be easier to add () at the end than type "m_" at the beginning).

std::cout << "Measuring file " << nomefile << std::endl;

would become

std::cout << "Measuring file " << m_nomefile << std::endl;

or better:

std::cout << "Measuring file " << nomefile() << std::endl;

Upvotes: 7

Related Questions