C++ 班级组成和结构顺序?

C++ 班级组成和结构顺序?,c++,constructor,composition,C++,Constructor,Composition,我有两个类,Time和Date,Date由一个Time对象组成。我对时间对象有问题。测试程序(我不允许修改)创建一个时间对象,然后创建一个日期对象,并将时间对象作为参数传递。当第一次创建对象时,它会正确初始化,但当调用日期对象构造函数时,它不会使用原始时间对象的参数。相反,它创建了一个新的时间对象,并使用我的默认参数(0,0,0),该参数必须包含在我的时间构造函数和时间类定义中 我想做的是将提供给Time对象的参数传递给Date构造函数的Time参数,这样时间构造函数就不会使用默认的(0,0,0

我有两个类,Time和Date,Date由一个Time对象组成。我对时间对象有问题。测试程序(我不允许修改)创建一个时间对象,然后创建一个日期对象,并将时间对象作为参数传递。当第一次创建对象时,它会正确初始化,但当调用日期对象构造函数时,它不会使用原始时间对象的参数。相反,它创建了一个新的时间对象,并使用我的默认参数(0,0,0),该参数必须包含在我的时间构造函数和时间类定义中

我想做的是将提供给Time对象的参数传递给Date构造函数的Time参数,这样时间构造函数就不会使用默认的(0,0,0)参数。我尝试使用对时间对象的引用,但无法使其工作

这是我的两个类头和测试代码。请注意,不允许更改测试代码。我考虑过在创建日期对象时只向其添加参数,但不允许修改该代码

测试代码:

#include <iostream> 
using std::cout; 
using std::endl; 

#include "Time.h" // include Time class definition
#include "Date.h" // include Date class definition

const int MAX_TICKS = 20;

int main()
{
   Time t(23, 59, 58);// create a time object
   Date d(12, 31, 2014, t); // create date object

   // output Time object t's values 
   for ( int ticks = 1; ticks < MAX_TICKS; ++ticks ) 
   {
      d.print(); // invokes print 
      cout << endl;
      d.tick(); // invokes function tick
   } // end for
   d.~Date();// call Date destructor
   system("PAUSE");
   return 0;
} // end main
时间标题:

#ifndef TIME_H
#define TIME_H

// Time class definition
class Time 
{
public:
   explicit Time( int = 0, int = 0, int = 0 ); // default constructor
   ~Time();  // destructor
   // set functions
   void setTime( int, int, int ); // set hour, minute, second
   void setHour( int ); // set hour (after validation)
   void setMinute( int ); // set minute (after validation)
   void setSecond( int ); // set second (after validation)

   // get functions
   unsigned int getHour() const; // return hour
   unsigned int getMinute() const; // return minute
   unsigned int getSecond() const; // return second

   void printUniversal() const; // output time in universal-time format
   void printStandard() const; // output time in standard-time format
private:
   unsigned int hour; // 0 - 23 (24-hour clock format)
   unsigned int minute; // 0 - 59
   unsigned int second; // 0 - 59
}; // end class Time

#endif
日期类实现文件:

// Date class member-function definitions.
#include <array>
#include <iostream>
#include <stdexcept>
#include "Date.h" // include Date class definition
#include "Time.h" // include the Time class definition
using namespace std;

// constructor confirms proper value for month; calls
// utility function checkDay to confirm proper value for day
Date::Date( int mn, int dy, int yr, Time time)
{
   if ( mn > 0 && mn <= monthsPerYear ) // validate the month
      month = mn;
   else 
      throw invalid_argument( "month must be 1-12" );

   year = yr; // could validate yr
   day = checkDay( dy ); // validate the day
   // output Date object to show when its constructor is called
   cout << "Date object constructor for date ";
   print();                   
   cout << endl;
} // end Date constructor



// print Date object in form month/day/year
void Date::print() const
{
   cout << month << '/' << day << '/' << year; 
   cout << "\t";
   time.printStandard();
   cout << "\t";
   time.printUniversal();
} // end function print

// output Date object to show when its destructor is called
Date::~Date()
{ 
   cout << "Date object destructor for date ";
   print();
   cout << endl;
} // end ~Date destructor

// function to increment Time by one second
void Date::tick()
{
   int tempSecond = time.getSecond();
   if (tempSecond < 59)
   {
      tempSecond++;
      time.setSecond(tempSecond);
   }
   else if (tempSecond >= 59)
   {
      time.setSecond(0);
      int tempMin = time.getMinute();
      if (tempMin < 59)
      {
         tempMin++;
         time.setMinute(tempMin);
      }
      else if (tempMin >= 59)
      {
         time.setMinute(0);
         int tempHour = time.getHour();
         if (tempHour < 23)
         {
            tempHour++;
            time.setHour(tempHour);
         }
         else if (tempHour >= 23)
         {
            time.setHour(0);
            increaseADay();
         }
      }
   }
}

void Date::increaseADay()
{
   checkDay(++day);
}

// utility function to confirm proper day value based on 
// month and year; handles leap years, too
unsigned int Date::checkDay( int testDay )
{
   static const array< int, monthsPerYear + 1 > daysPerMonth = 
      { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

   // determine whether testDay is valid for specified month
   if ( testDay > 0 && testDay <= daysPerMonth[ month ] )
      return testDay;

   // February 29 check for leap year 
   if ( month == 2 && testDay == 29 && ( year % 400 == 0 || 
      ( year % 4 == 0 && year % 100 != 0 ) ) )
      return testDay;
   if (testDay > daysPerMonth[month])
   {
      month++;
      day = 1;
      if (month > monthsPerYear)
      {
         year++;
         month = 1;
         day = 1;
         return 0;
      }
   }

   throw invalid_argument( "Invalid day for current month and year" );
} // end function checkDay
//日期类成员函数定义。
#包括
#包括
#包括
#包含“Date.h”//include日期类定义
#包括“Time.h”//包括时间类定义
使用名称空间std;
//建造商确认月的正确值;电话
//实用程序功能检查日,以确认日的正确值
日期:日期(整数年、整数年、整数年、时间)
{

如果(mn>0&&mn我正在查看您的
日期
构造函数,我突然想到一些事情:

  • 它以
    Date::Date(int mn,int dy,int yr,Time Time){
    开头,不使用
    ,这意味着
    Data::Time
    字段将使用
    Time
    的默认构造函数初始化
  • 您不使用构造函数的
    time
    参数,尤其是不将其分配给
    Data::time

我想这就解释了你的问题

我正在查看你的
日期
构造函数,有些事情让我印象深刻:

  • 它以
    Date::Date(int mn,int dy,int yr,Time Time){
    开头,不使用
    ,这意味着
    Data::Time
    字段将使用
    Time
    的默认构造函数初始化
  • 您不使用构造函数的
    time
    参数,尤其是不将其分配给
    Data::time

我想这就解释了你的问题

你必须在
日期
构造函数中设置
这个->时间;
。这就是你所缺少的。

你必须在
日期
构造函数中设置
这个->时间;
。这就是你所缺少的。

首先,你明确地调用了析构函数,它当
d
main
末尾再次被销毁时,会导致未定义的行为,因此在您解决此问题之前,您的问题的其余部分几乎没有意义。还有太多不相关的代码,并且没有任何代码可以真正解释您的问题。如果您指的是显式dest,请使用这是我的老师提供的代码,他说我的对象必须使用它…除非你的老师告诉你“请不要在真实代码中这样做”我对他的C++教学能力很怀疑。明确的调用不仅是错误的,它绝对没有目的, D<代码>在 T之前已经被销毁。我看到你已经删除了代码,但是你仍然没有为你的构造函数提供定义。请再次阅读MVCE链接,你需要发布一些THA。我可以同意你对他的C++教学能力的怀疑。过去我已经纠正过他,他在我的作业中把新的C++ 11用于数据成员的类初始化特性,我还得纠正他,因为他用了推荐的数组类来分级我。模板,而不是内置的C样式数组。遗憾的是,他仍然是我的老师,我仍然必须使用他给我的东西。关于我的代码,如果我包括所有内容,包括我的两个类实现文件,那就更好了。我不能剪切部分并期望它编译…没关系,只要它能编译。我猜析构函数调用这是因为在调用
pause
以保持命令窗口打开之前,
d
不会被销毁。这可以通过从打开的命令窗口运行应用程序,或者通过引入新的块范围来强制销毁
t
d
来轻松解决。For初学者您显式调用析构函数,当
d
main
末尾再次被销毁时,会导致未定义的行为,因此在您解决此问题之前,您的问题的其余部分几乎没有意义。还有太多不相关的代码,并且没有任何代码可以真正解释您的问题。请重写您的问题问一个问题。如果你指的是测试代码中的显式析构函数调用,我是不允许更改的。这是我老师提供的代码,他说我的对象必须使用它…除非你的老师告诉你“请不要在真实代码中这样做”我对他的C++教学能力很怀疑。明确的调用不仅是错误的,它绝对没有目的, D<代码>在 T之前已经被销毁。我看到你已经删除了代码,但是你仍然没有为你的构造函数提供定义。请再次阅读MVCE链接,你需要发布一些THA。T可以被复制、粘贴和编译,我同意你怀疑他的C++教学能力。我已经不得不纠正他。
// Date class member-function definitions.
#include <array>
#include <iostream>
#include <stdexcept>
#include "Date.h" // include Date class definition
#include "Time.h" // include the Time class definition
using namespace std;

// constructor confirms proper value for month; calls
// utility function checkDay to confirm proper value for day
Date::Date( int mn, int dy, int yr, Time time)
{
   if ( mn > 0 && mn <= monthsPerYear ) // validate the month
      month = mn;
   else 
      throw invalid_argument( "month must be 1-12" );

   year = yr; // could validate yr
   day = checkDay( dy ); // validate the day
   // output Date object to show when its constructor is called
   cout << "Date object constructor for date ";
   print();                   
   cout << endl;
} // end Date constructor



// print Date object in form month/day/year
void Date::print() const
{
   cout << month << '/' << day << '/' << year; 
   cout << "\t";
   time.printStandard();
   cout << "\t";
   time.printUniversal();
} // end function print

// output Date object to show when its destructor is called
Date::~Date()
{ 
   cout << "Date object destructor for date ";
   print();
   cout << endl;
} // end ~Date destructor

// function to increment Time by one second
void Date::tick()
{
   int tempSecond = time.getSecond();
   if (tempSecond < 59)
   {
      tempSecond++;
      time.setSecond(tempSecond);
   }
   else if (tempSecond >= 59)
   {
      time.setSecond(0);
      int tempMin = time.getMinute();
      if (tempMin < 59)
      {
         tempMin++;
         time.setMinute(tempMin);
      }
      else if (tempMin >= 59)
      {
         time.setMinute(0);
         int tempHour = time.getHour();
         if (tempHour < 23)
         {
            tempHour++;
            time.setHour(tempHour);
         }
         else if (tempHour >= 23)
         {
            time.setHour(0);
            increaseADay();
         }
      }
   }
}

void Date::increaseADay()
{
   checkDay(++day);
}

// utility function to confirm proper day value based on 
// month and year; handles leap years, too
unsigned int Date::checkDay( int testDay )
{
   static const array< int, monthsPerYear + 1 > daysPerMonth = 
      { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

   // determine whether testDay is valid for specified month
   if ( testDay > 0 && testDay <= daysPerMonth[ month ] )
      return testDay;

   // February 29 check for leap year 
   if ( month == 2 && testDay == 29 && ( year % 400 == 0 || 
      ( year % 4 == 0 && year % 100 != 0 ) ) )
      return testDay;
   if (testDay > daysPerMonth[month])
   {
      month++;
      day = 1;
      if (month > monthsPerYear)
      {
         year++;
         month = 1;
         day = 1;
         return 0;
      }
   }

   throw invalid_argument( "Invalid day for current month and year" );
} // end function checkDay
#include <iostream>
#include <iomanip>
#include <stdexcept>
#include "Time.h" // include definition of class Time from Time.h
using namespace std;

// Time constructor initializes each data member 
Time::Time( int hour, int minute, int second ) 
{ 
   cout << "Time object constructor is called ";
   setTime( hour, minute, second ); // validate and set time
   cout << "\t";
   printStandard();  // call the print standard function
   cout << "\t";
   printUniversal(); // call the print universal function.
   cout << endl;
} // end Time constructor

// Time destructor - calls printStandard and printUniversal
Time::~Time()
{
   // print a message indicating that we are destructing
   cout << "Time object destructor called.";
   // call printStandard and printUniversal functions
   printStandard();
   printUniversal();
} // end Time destructor

// set new Time value using universal time
void Time::setTime( int h, int m, int s )
{
   setHour( h ); // set private field hour
   setMinute( m ); // set private field minute
   setSecond( s ); // set private field second
} // end function setTime

// set hour value
void Time::setHour( int h )
{
   if ( h >= 0 && h < 24 )  // validate the input
      hour = h;
   else                     // throw an error if hour is not valid.
      throw invalid_argument( "hour must be 0-23" );
} // end function setHour

// set minute value
void Time::setMinute( int m )
{
   if ( m >= 0 && m < 60 )  // validate the input
      minute = m; 
   else                     // throw an error if hour is not valid.
      throw invalid_argument( "minute must be 0-59" );
} // end function setMinute

// set second value
void Time::setSecond( int s )
{
   if ( s >= 0 && s < 60 )
      second = s;
   else
      throw invalid_argument( "second must be 0-59" );
} // end function setSecond

// return hour value
unsigned int Time::getHour() const
{
   return hour;
} // end function getHour

// return minute value
unsigned int Time::getMinute() const
{
   return minute;
} // end function getMinute

// return second value
unsigned int Time::getSecond() const
{
   return second;
} // end function getSecond

// print Time in universal-time format (HH:MM:SS)
void Time::printUniversal() const
{
   // set field widths and fill characters to print format "00:00:00"
   // setfill is sticky, setw is not
   cout << setfill( '0' ) << setw( 2 ) << getHour() << ":"
      << setw( 2 ) << getMinute() << ":" << setw( 2 ) << getSecond();
} // end function printUniversal

// print Time in standard-time format (HH:MM:SS AM or PM)
void Time::printStandard() const
{
   // set field widths and fill characters to print format "00:00:00"
   // use the conditional operator to check if time is equal to 0 or 12
   // if so, mod the hour by 12 to put it in 12 hour clock format.
   cout << ( ( getHour() == 0 || getHour() == 12 ) ? 12 : getHour() % 12 )
      << ":" << setfill( '0' ) << setw( 2 ) << getMinute()
      << ":" << setw( 2 ) << getSecond() << ( hour < 12 ? " AM" : " PM" );
} // end function printStandard