简体   繁体   中英

C++ classes and variables

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 taa "time" variable?

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM