1

これは、 C++によるインスタンスレベルのカプセル化からのフォローアップ投稿です。

クラスを定義し、そのクラスから2つのオブジェクトを作成しました。

#include <iostream>
#include <ctime>
#include <string>

using namespace std;

class timeclass {
  private:
  string date;

  time_t gmrawtime, rawtime;
  struct tm * timeinfo;
  char file_date[9];

  void tm_init(int);

public:
  timeclass(int);
  void print_date();
};

void timeclass::tm_init(int y) {
  timeinfo = gmtime(&rawtime);
  timeinfo->tm_year = y - 1900; // timeinfo->tm_year holds number of years since 1900
  timeinfo->tm_mon = 0;
  timeinfo->tm_mday = 1;
  timeinfo->tm_hour = 0;
  timeinfo->tm_min= 0;
  timeinfo->tm_sec= 0;
}

timeclass::timeclass(int y) {
  timeclass::tm_init(y);
  gmrawtime = mktime(timeinfo) - timezone; 
}

void timeclass::print_date() {
  strftime(file_date,9,"%Y%m%d",timeinfo);

  date = string(file_date);
  cout<<date<<endl;
}

/* -----------------------------------------------------------------------*/

int main()
{
  timeclass time1(1991); 
  timeclass time2(1992); 

  time1.print_date(); // Prints 19920101, despite being initialized with 1991
  time2.print_date(); // Prints 19920101, as expected

  return 0;
}

この例は、私のメインプログラムからスライスしてさいの目に切った日付カウンターの一部ですが、私のポイントを示しています。クラスのインスタンス(time1とtime2)ごとに日付カウンターを実行したいのですが、time2オブジェクトを作成すると、time1にカプセル化されていると思っていた'timeinfo'変数がtime2コンストラクターによって上書きされるようです。

C ++はクラスレベルのカプセル化のみをサポートしていることを認識しており、同じクラスのメンバーが互いのプライベートメンバーにアクセスできるために問題が発生するのではないかと考えています。これを回避する方法はありますか?私がやりたいことを達成することができますか?ありがとう、テイラー

4

3 に答える 3

5

gmtime()localtime()ctime()およびasctime()静的データへのポインターを返します。したがって、後続の呼び出しは、以前の呼び出しによって書き込まれた情報を上書きする可能性があります。これは、これらの呼び出しがスレッドセーフではないことも意味しますが、この場合、複数のスレッドは関与していません。

他の回答は、この制限に対する可能な回避策を提供しています。

于 2013-03-08T21:16:16.293 に答える
2

あなたは実際には望んでいませんgmtime()Shafik's answerを参照)。std::tm変更できるものが必要なだけです:

void timeclass::tm_init(int y) {
  timeinfo = new std::tm;
  timeinfo->tm_year = y - 1900;
  timeinfo->tm_mon = 0;
  timeinfo->tm_mday = 1;
  timeinfo->tm_hour = 0;
  timeinfo->tm_min= 0;
  timeinfo->tm_sec= 0;
}

Shafik が既に書いたように、あなたの問題は、あなたが指摘するstd::tm多くの*time()メソッドで使用される内部静的です。したがって、独自の を作成するstd::tmか、さらに単純に、ポインターの代わりにメンバーとして使用します。

class timeclass {
  private:
  std::tm timeinfo;
  /* rest stays the same */
};

void timeclass::tm_init(int y) {
  timeinfo = *std::gmtime(&rawtime); // if you need gmtime
  timeinfo.tm_year = y - 1900;
  timeinfo.tm_mon = 0;
  timeinfo.tm_mday = 1;
  timeinfo.tm_hour = 0;
  timeinfo.tm_min= 0;
  timeinfo.tm_sec= 0;
}
于 2013-03-08T21:19:24.670 に答える
0

他の人が指摘したように、問題は、使用している関数がグローバル データを返すことです。したがって、あなたの質問は回避されました。

ただし、ご指摘のとおり、C++ はオブジェクト レベルではなくクラス レベルでカプセル化するため、どのオブジェクトでも同じクラスの他のオブジェクトのプライベート データを変更できます。

パラメータとクラスメンバーとして抽象クラスのみを使用することで、これを回避できます。

class Time {
public:
    virtual void setYear(int year) = 0;
    virtual void printDate() = 0;
    virtual void subtract(Time& otherTime) = 0;   
};
于 2013-03-08T21:35:19.997 に答える