Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ classes and variables

Tags:

c++

class

I'm relatively new to C++ programming. I'm studying how do classes work, and I have a problem with the following code:

#include <iostream>

using namespace std;

class time
{
public:
time();
void settime (int, int, int);
void printuniversal ();
void printstandard ();
private:
int hour;
int minute;
int second;
};

time::time()
{
hour = minute = second = 0;
}

void time::settime (int h, int m, int s)
{
hour = (h >= 0 && h < 24) ? h : 0;
minute = (m >= 0 && m < 60) ? m : 0;
second = (s >= 0 && s < 60) ? s : 0;
}

void time::printuniversal()
{
cout << hour << ":" << minute << ":" << second << ":" << endl;
}

void time::printstandard()
{
cout << ((hour == 0 || hour == 12) ? 12 : hour % 12) << ":" << minute << ":" << second                             << (hour < 12 ? "AM" : "PM") << endl;
}

int main ()
{
time t;
cout << "Initial universal time: " << t.printuniversal();
cout << "\nInitial standard time: " << t.printstandard();
t.settime(13,27,6);
cout << "\nNew universal time: " << t.printuniversal();
cout << "\nNew standard time: " << t.printstandard();
return 0;
}

The mistake I get is: classi.cpp:42:6: error: expected ‘;’ before ‘t’ classi.cpp:43:39: error: ‘t’ was not declared in this scope

Is there something I didn't quite understand about classes? Why doesn't it recognize t a a "time" variable?

like image 841
Wreyh Avatar asked Jun 23 '13 13:06

Wreyh


People also ask

What is variables in C?

Variable is basically nothing but the name of a memory location that we use for storing data. We can change the value of a variable in C or any other language, and we can also reuse it multiple times. We use symbols in variables for representing the memory location- so that it becomes easily identifiable by any user.

What is the difference C storage class of a variable?

A variable given in a C program will have two of the properties: storage class and type. Here, type refers to any given variable's data type, while the storage class determines that very variable's lifetime, visibility, and also its scope.

What are different classes in C?

The four storage classes in C are declared in a block or program with the storage class specifiers, auto, register, extern, static. There is one more storage class specifier, 'typedef' used in the syntactic form, and does not reserve storage. The specifiers instruct the compiler on storing the variables.


3 Answers

This should teach you not to have nasty using directives such as:

using namespace std;

And especially not at namespace scope (even worse if in header files). There is a function in the standard library called std::time(), whose name is clashing with the name of your type.

This ambiguity can be solved by using the class keyword in the declaration of t:

class time t;

However, a much better way would be to remove the using directive and qualify the names of entities from the standard namespace, thus writing (for instance):

   std::cout << "Initial universal time: "
// ^^^^^

Notice, that this may not be enough, since library implementations are allowed to put entities from the C standard library in the global namespace. In this case, removing the nasty using directive would not help resolving the ambiguity.

Therefore, I would also suggest avoiding to give your own entities (types, functions, variables, ...) the same name as entities from the standard library, or to put them in your own namespace at least.

Moreover, expressions such as:

cout << "Initial universal time: " << t.printuniversal();
//                                 ^^^^^^^^^^^^^^^^^^^^^
//                                 printuniversal() returns void! 

Are ill-formed, since printuniversal() returns void. You should just do:

cout << "Initial universal time: ";
t.printuniversal();

The same applies of course to all similar expressions

like image 104
Andy Prowl Avatar answered Sep 20 '22 17:09

Andy Prowl


You shouldn't name your class time, or you should avoid using using namespace std. Instead, you can do statements like using std::cout, using std::endl, etc. I personally never use "using", always leave std::, it makes easier my searches in the source code.

Anyway, I checked here, removing using namespace std doesn't really help (see discussion above). Play safe and change name to the class. Anyway, the above suggestions stay.

like image 34
Antonio Avatar answered Sep 20 '22 17:09

Antonio


An alternative to removing the "using namespace std" directive is to place your code in a namespace to avoid clashing names. This can be done as follows:

namespace time_utils
{
    class time
    {
    public:
        time();
        void settime (int, int, int);
        void printuniversal ();
        void printstandard ();
    private:
        int hour;
        int minute;
        int second;
    };
};

time_utils::time::time()
{
    hour = minute = second = 0;
}

The purpose of namespaces is to avoid clashing names.

Later on there are compilation errors when calling functions in the cout stream, so you can split them up like so:

int main ()
{
    my_code::time t;
    cout << "Initial universal time: ";
    t.printuniversal();
    cout << "\nInitial standard time: ";
    t.printstandard();
    t.settime(13,27,6);
    cout << "\nNew universal time: ";
    t.printuniversal();
    cout << "\nNew standard time: ";
    t.printstandard();
    return 0;
}

That's because those functions are returning void. The alternative there is to have those functions return std::string instead.

Hope this offers an alternative insight.

Cheers,

Simon.

like image 34
Simon Bosley Avatar answered Sep 18 '22 17:09

Simon Bosley