如何更改默认构造函数的参数?
Posted
技术标签:
【中文标题】如何更改默认构造函数的参数?【英文标题】:How can I change the parameters of a default constructor? 【发布时间】:2020-09-09 16:33:00 【问题描述】:我有一个名为Date
的类来控制日期。
我有一个构造函数Date()
。如果此构造函数未初始化,则默认日期将由名为 default_
的私有静态数据成员代替。
我已经在Date.cpp
中初始化了default_
,如下:
Date Date::default_1, Month::January, 1900;
其中第一个参数是 int
代表当天,第二个参数是 enum class
Month
代表月份,第三个是 int
代表年份。
当我运行这个程序时,我可以打印日期,它会显示由default_
设置的正确默认日期。
问题:
我希望能够使用函数更改默认日期:
setDefaultDate(int day, Month month, int year)
我该怎么做?我尝试如下实现setDefaultDate()
,但它不起作用:
void Date::setDefaultDate(int day, Month month, int year)
default_ = day,month,year;
代码:
日期.h:
#ifndef DATE_H
#define DATE_H
// date.h
// class Date declaration
#include <cassert>
#include <iostream>
using namespace std;
enum class Month
January = 1,
February,
March,
April,
May,
June,
July,
August,
September,
October,
November,
December
;
class Date
public:
// return the day of the month
int day () const;
// return the month of the year
Month month () const;
// return the year
int year () const;
Date();
static void setDefaultDate(int day, Month month, int year);
private:
int day_;
Month month_;
int year_;
static Date default_;
;
// standalone function for printing the date
void printDate(const Date& date);
#endif
日期.cpp:
// date.cpp
// Implementation of the Date class
#include "date.h"
int Date::day() const
return day_;
Month Date::month() const
return month_;
int Date::year() const
return year_;
// Note, this standalone function is not part of the Date class
void printDate(const Date& date)
cout << date.day() << "/"
// cast to an integer to allow the month to be sent to the stream
<< static_cast<int>(date.month()) << "/"
<< date.year()
<< endl;
Date Date::default_1, Month::January, 1900;
void Date::setDefaultDate(int day, Month month, int year)
default_ = day,month,year;
Date::Date()
day_ = default_.day();
month_ = default_.month();
year_ = default_.year();
示例
int main()
auto date_1 = Date;
date_1.setDefaultDate(29, Month::September, 2020);
printDate(date_1);
预期输出: 2020 年 9 月 29 日
实际输出: 1900 年 1 月 1 日
它可以编译,但是setDefaultDate()
函数不起作用,并且正在输出default_
中声明的默认日期。
【问题讨论】:
“它不工作:” 是没有问题的描述。请添加更多细节。此外,您的标题有点误导,因为默认构造函数不接受您可以更改的任何参数。 你没有三参数构造函数(添加Date::Date(int day, Month month, int year)
)
“如果此构造函数未初始化,默认日期将由名为 'default_' 的私有静态数据成员放置在其位置” 为什么?只需初始化构造函数中的成员。不需要这个default_
变量。
你说的代码为我编译了does not compile,因为缺少默认日期初始化的构造函数。 setDefaultDate
还没进图呢。
@John 那么请澄清 what 不起作用。最好的方法是minimal reproducible example,它准确地重现您现在遇到的错误。
【参考方案1】:
让我们逐行浏览您的main
:
auto date_1 = Date;
这会做什么?它将调用Date::Date
,它将从default_
读取所有值到date_1
。此时default_
是1/1/1900
和date_1
现在是一样的。那么
date_1.setDefaultDate(29, Month::September, 2020);
将仅更改 default_
和 default_
。我不确定您为什么期望 date_1
在这里更改,可能是因为您将其称为非静态成员函数?您可能打算更改默认日期 before 从中读取。你可以这样做:
int main()
// call it like static function
Date::setDefaultDate(29, Month::September, 2020);
// Only then read from it.
auto date_1 = Date;
// prints 29/9/2020
printDate(date_1);
【讨论】:
【参考方案2】:您的setDefaultDate()
方法仅设置default_
的值,main()
在为date_1
对象调用Date()
构造函数时已经复制了该值。之后更改default_
的值对date_1
的值没有任何影响。当你打印date_1
时,你输出它初始化的值。更改default_
的值只会影响后续您之后创建的Date
对象。
如果你想改变date_1
的值,你需要:
-
致电
setDefaultDate()
之前致电Date()
:
int main()
Date::setDefaultDate(29, Month::September, 2020);
Date date_1;
printDate(date_1); // 29/9/2020
-
添加非静态方法来改变
Date
对象的值。您还应该添加一个可以将用户指定的日期作为输入的非默认构造函数,例如:
class Date
public:
Date();
Date(int initialDay, Month initialMonth, int initialYear);
...
void setDay (int newValue);
void setMonth (Month newValue);
void setYear (int newValue);
...
;
Date::Date() :
Date(default_.day_, default_.month_, default_.year_)
Date::Date(int initialDay, Month initialMonth, int initialYear) :
day_(initialDay),
month_(initialMonth),
year_(initialYear)
void Date::setDay (int newValue)
day_ = newValue;
void Date::setMonth (Month newValue)
month_ = newValue;
void Date::setYear (int newValue)
year_ = newValue;
...
int main()
Date date_1;
printDate(date_1); // 1/1/1900
date_1.setDay(29);
date_1.setMonth(Month::September);
date_1.setYear(2020);
printDate(date_1); // 29/9/2020
date_1 = Date(9, Month::September, 2020);
printDate(date_1); // 9/9/2020
Date date_2(31, Month::December, 2020);
printDate(date_2); // 31/12/2020
Date::setDefaultDate(1, Month::April, 2020);
Date date_3;
printDate(date_3); // 1/4/2020
【讨论】:
【参考方案3】:如果我理解正确,我将向您展示您的代码的修改版本,该版本应该可以满足您的需求。为了使用单个文件,我稍微更改了您的代码
java 不是 C++,C++ 不是 java。而static
C++ 中的东西不是 java 的方式。也许你已经习惯了。
在 C++ 中,您可以将默认运行代码设置为 main()
之外 和类之外
...
; // class Date
int Date::default_day = 1;
int Date::default_month = 1;
int Date::default_year = 1900;
void printDate(const Date& date);
void setDefaultDate(int, int, int);
int main(void)
...
所以你已经加载了第一组默认值。
对于如果你在
main()
内执行它,它会编译,但链接器会 抱怨他们三个都没有解决。
setDefaultDate()
,您可以将其声明为日期的friend
friend void setDefaultDate(int, int, int);
PrintDate()
的一种方便且常见的替代方法是将另一个 friend
声明为 Date
,如下所示
friend ostream& operator<<(ostream&, Date&);
使用您的代码的示例
节目展示
just a date at start (should use defaults 1900,1,1)
printDate()
d: 1 m: 1 y: 1900
Now sets default to 1901/3/2
printDate()
d: 2 m: 3 y: 1901
Now declared new Date instance as d3(2019,8,7)
printDate()
d: 7 m: 8 y: 2019
Now print all 3 dates using "<<" operator, redefined for Date class
printDate using insertion operator '<<'
year is 1900 month is 1 year is 1900
printDate using insertion operator '<<'
year is 1901 month is 3 year is 1901
printDate using insertion operator '<<'
year is 2019 month is 8 year is 2019
main()
是
int main(void)
cout << "\njust a date at start (should use defaults 1900,1,1)\n";
Date d1;
printDate(d1);
cout << "\nNow sets default to 1901/3/2\n";
setDefaultDate(2, 3, 1901);
Date d2;
printDate(d2);
cout << "\nNow declared new Date instance as d3(2019,8,7)\n";
Date d3(2019, 8, 7);
printDate(d3);
cout << "\nNow print all 3 dates using \"<<\" operator, redefined for Date class\n";
cout << d1 << d2;
cout << d3;
return 0;
代码使用printDate()
和重载的<<
作为printDate()
的替代品。我为 3 个 Date
留下了两个 cout
,只是为了表明您可以像使用任何其他 cout
调用一样链接打印。
程序设置默认值before和insidemain()
我添加了第二个构造函数,它接受 day
、month
和 year
作为参数
完整的例子
#include <iostream>
using namespace std;
class Date
private:
int year_;
int month_;
int day_;
public:
int year() const return year_; ;
int month() const return month_; ;
int day() const return day_; ;
// default as Date d;
Date() :
year_(default_year), month_(default_month), day_(default_day) ;
// as Date d(2020,9,8)
Date(int y, int m, int d) :
year_(y), month_(m), day_(d);
friend void setDefaultDate(int, int, int);
friend ostream& operator<<(ostream&, Date&);
private:
static int default_year;
static int default_month;
static int default_day;
; // class Date
int Date::default_day = 1;
int Date::default_month = 1;
int Date::default_year = 1900;
void printDate(const Date& date);
void setDefaultDate(int, int, int);
int main(void)
cout << "\njust a date at start (should use defaults 1900,1,1)\n";
Date d1;
printDate(d1);
cout << "\nNow sets default to 1901/3/2\n";
setDefaultDate(2, 3, 1901);
Date d2;
printDate(d2);
cout << "\nNow declared new Date instance as d3(2019,8,7)\n";
Date d3(2019, 8, 7);
printDate(d3);
cout << "\nNow print all 3 dates using \"<<\" operator, redefined for Date class\n";
cout << d1 << d2;
cout << d3;
return 0;
void printDate(const Date& date)
cout << "\nprintDate()\n" <<
" d: " << date.day() <<
" m: " << date.month() <<
" y: " << date.year()
<< endl;
;
void setDefaultDate(int day, int month, int year)
Date::default_day = day;
Date::default_month = month;
Date::default_year = year;
;
ostream& operator<<(ostream& out, Date& date)
cout << "\nprintDate using insertion operator '<<'\n" <<
"\tyear is " << date.year_ <<
" month is " << date.month_ <<
" year is " << date.year_ <<
endl;
return out;
;
这里没有宗教。我是在 MSVC 19.27
下编译的【讨论】:
以上是关于如何更改默认构造函数的参数?的主要内容,如果未能解决你的问题,请参考以下文章