6

私はC++プログラミングに比較的慣れていません。クラスがどのように機能するかを研究していますが、次のコードに問題があります。

#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;
}

私が得る間違いは次のとおりです:classi.cpp:42:6:エラー:期待される ';' 't' の前に classi.cpp:43:39: エラー: 't' はこのスコープで宣言されていませんでした

授業についてよくわからないことはありますか?taa「時間」変数を認識しないのはなぜですか?

4

3 に答える 3

14

usingこれにより、次のような厄介なディレクティブを使用しないように教える必要があります。

using namespace std;

特に名前空間のスコープではありません (ヘッダー ファイルの場合はさらに悪い)。という名前の標準ライブラリに関数がありstd::time()、その名前はあなたの型の名前と衝突しています。

このあいまいさはclass、の宣言でキーワードを使用することで解決できtます。

class time t;

ただし、より良い方法は、usingディレクティブを削除し、標準の名前空間からエンティティの名前を修飾して、次のように記述することです (たとえば)。

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

ライブラリの実装では C 標準ライブラリのエンティティをグローバル名前空間に配置できるため、これでは不十分な場合があることに注意してください。この場合、厄介なusingディレクティブを削除しても、あいまいさの解決には役立ちません。

したがって、独自のエンティティ (型、関数、変数など) に標準ライブラリのエンティティと同じ名前を付けるか、少なくとも独自の名前空間に配置することを避けることもお勧めします。

また、次のような表現:

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

printuniversal()を返すため、形式が正しくありませんvoid。あなたはただやるべきです:

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

同じことはもちろんすべての同様の表現にも当てはまります

于 2013-06-23T14:00:44.713 に答える
3

クラスに名前を付けないでください。timeまたは、の使用を避ける必要がありますusing namespace stdusing std::cout代わりに、、などのステートメントを実行できますusing std::endl。私は個人的に「using」を使用せず、常に std:: のままにします。これにより、ソース コードでの検索が容易になります。

とにかく、ここで確認しましたが、削除using namespace stdしてもあまり役に立ちません (上記の説明を参照)。安全にプレイして、名前をクラスに変更します。とにかく、上記の提案は残ります。

于 2013-06-23T14:01:05.600 に答える
3

「using namespace std」ディレクティブを削除する代わりに、コードを名前空間に配置して、名前の衝突を回避します。これは次のように行うことができます。

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;
}

名前空間の目的は、名前の衝突を避けることです。

後で cout ストリームで関数を呼び出すとコンパイル エラーが発生するため、次のように分割できます。

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;
}

これは、これらの関数が void を返しているためです。代わりに、これらの関数が std::string を返すようにすることもできます。

これが別の洞察を提供することを願っています。

乾杯、

サイモン。

于 2013-06-23T22:30:37.410 に答える