使用以下代码,在类中声明成员函数,它会提示用户输入各种输入,如小时和付费。
cout << endl << "Now please input info #1" << endl;
Info p1;
cout << endl << "Now please input info #2" << endl;
Info p2;
p2.combineinfo(p1); /**< combines the info, like hours, pay, ect. */
printinfo(pnew); /**< prints out the combined paycheck information */
信息准确地放入p1
和p2
,因为我可以使用cout
进行确认。但是,p2.combineinfo(p1)
再次提示输入一组信息。我不想要这个,我只需要传递给这个函数来合并,然后用printinfo();
打印出来。
Info Info::combineInfo(Info p1)
{
Info p2;
Info pnew;
pnew.name = p1.name;
pnew.hours = p1.hours + p2.hours;
pnew.total = p1.total + p2.total;
return pnew;
}
更新信息:
Info::Info()
{
string dummy;
cout << "question here"<<endl;
getline(cin, a);
cout <<"question here"<<endl;
cin >> b;
getline(cin, dummy);
cout <<"question here"<<endl;
cin >> c;
getline(cin, dummy);
cout << "quesiton here"<< endl;
initializeDate(start);
cout << "question here "<< endl;
initializeDate(finish);
}
答案 0 :(得分:1)
您没有显示它,但您可能要求Info构造函数中的输入。类似的东西:
Info::Info()
{
cout << "Enter name: ";
cin >> name;
cout << "Enter hours: ";
cin >> hours;
cout << "Enter total: ";
cin >> total;
}
因此,在combineInfo中,您创建了两个Info类对象,因此构造函数会运行并请求每个对象的输入。只是不要求构造函数中的值。添加另一个方法AskForInput来询问值,不要从构造函数中调用它。
答案 1 :(得分:1)
我猜你正在读取你的构造函数中的stdin输入信息(你可以发布这个代码吗?)。因此,当你再次创建p2和pnew时,它会调用相同的代码。
我建议您使用stdin而不是构造函数来初始化变量的单独代码。否则,你可以在这里做很多关于被召唤的事情!
答案 2 :(得分:0)
由于我最后输入了很多评论,我把它组合成一个答案:
根据其他答案,您的问题是您在Info
函数中调用combineInfo
的构造函数,并且您在构造函数中提示用户。在构造函数中使用std::cin
通常是一个坏主意 - 如果您(或您的代码的用户)决定在std::cin
不合适的情况下使用代码(例如,当您稍后决定升级到GUI)?如果要使用预定数据构造对象,该怎么办?还是在单元测试中?
事实上,您自己的代码提供了这样一个示例:您已经定义了Info
,其唯一的方法是通过向用户请求信息来构建它。但是,您实际上想要构建对象的两种方式 - (1)通过提示来自用户的信息,以及(2)通过组合已存在的信息在另外两个Info
对象(p1
和p2
)内。
更好的解决方案是让构造函数通过参数 - Info::Info(string name, int hours, int total)
接收数据,从类外部的用户(适当时)获取信息,并将其传递给构造函数。
或者,如果您决定将cin
代码保留在构造函数中,则不要使用compareInfo()
函数 - 创建一个第二个构造函数,该构造函数需要两个{ {1}}对象作为参数,并将代码放在那里:
Info
然后按照这样的方式进行组合:
Info::Info(Info p1, Info p2)
{
name = p1.name;
hours = p1.hours + p2.hours;
total = p1.total + p2.total;
}
编辑:你评论说你必须坚持一个标准,即组合必须在Info pnew(p1, p2);
函数中发生。这很尴尬,因为您的构造函数会提示输入信息,您必须在成员函数中构造一个临时的Info Info::combineInfo(Info)
对象:
Info
你有三个我能想到的解决方案,其中没有一个特别有吸引力(我很惊讶老师会对你强加这个要求):
(1)提供一个不提示信息的构造函数。但是它必须与请求信息的签名具有不同的签名,因为您无法定义两次默认构造函数:
Info Info::combineInfo(Info p1)
{
Info pnew; // Temporary Info object
pnew.name = p1.name;
pnew.hours = p1.hours + hours;
pnew.total = p1.total + total;
return pnew;
}
然后,当您创建Info::Info()
{
// Prompt user.
}
Info::Info(int dummyValue)
{
// Do nothing.
}
对象时,请调用第二个构造函数:pnew
。
(2)根本不提供默认构造函数,而是创建一个通知是否提示:
Info pnew(0);
这样做的缺点是你总是需要提供一个参数来构造Info对象:
Info::Info(bool prompt)
{
if (prompt)
{
// Construct object by prompting user.
}
// No need to do an else, simply do nothing if !prompt
}
(3)根本不要创建临时Info p1; // Error, no default constructor
Info p1(true); // Construct by prompting
Info pnew(false); // Construct without prompting
,只需修改pnew
并返回即可。这是糟糕的风格,只有通过p1
按值传递才有效(因此您不会修改原始p1
):
p1
您的代码中也存在一些错误:
Info Info::combineInfo(Info p1)
{
// No need to do anything with name since it's p1's name you want anyway
p1.hours += hours;
p1.total += total;
return p1;
}
将代码更改为:
cout << endl << "Now please input info #1" << endl;
Info p1;
cout << endl << "Now please input info #2" << endl;
Info p2;
p2.combineinfo(p1); // You are not saving the return value.
printinfo(pnew); // pnew does not exist, see above.
第二个错误如下:
cout << endl << "Now please input info #1" << endl;
Info p1;
cout << endl << "Now please input info #2" << endl;
Info p2;
Info pnew = p2.combineinfo(p1); // Now you are saving the result.
printinfo(pnew); // pnew now exists.
由于构造函数问题,只有似乎似乎才能正常工作 - 系统会提示您输入Info Info::combineInfo(Info p1)
{
Info p2; // You're creating a new p2 object, this is
// NOT the p2 you called the function on.
Info pnew;
pnew.name = p1.name;
pnew.hours = p1.hours + p2.hours; // Wrong p2
pnew.total = p1.total + p2.total; // Wrong p2
return pnew;
}
的{{1}}的信息,因此它最终与您实际打算使用的combineInfo
相同(假设您再次输入相同的数据),它似乎正确地组合它们。这样做:
p2
在这种情况下, p2
和Info Info::combineInfo(Info p1)
{
// Info p2; // Delete this line
// your intended p2 is passed to the function as the implicit parameter.
Info pnew;
pnew.name = p1.name;
pnew.hours = p1.hours + hours; // hours refers to implicit parameter
pnew.total = p1.total + total; // total refers to implicit parameter
return pnew;
}
是hours
和total
的简写。
要考虑将来参考的另一件事是重载this.hours
运算符而不是编写组合函数:
this.total
现在而不是:
+
你可以写:
Info Info::operator+(Info p1)
{
Info pnew;
pnew.name = p1.name;
pnew.hours = p1.hours + hours;
pnew.total = p1.total + total;
return pnew;
}
最后,考虑通过引用而不是按值传递 - 对于非平凡对象,函数通常更快地取消引用地址而不是创建它的新副本:
Info pnew = p2.combineInfo(p1);
编辑:但如果您使用上面的解决方案3,请不要这样做,否则您将修改可能不适合您的原始Info pnew = p1 + p2;
。
答案 3 :(得分:0)
据推测,您已决定使用Info
读取值的默认构造函数。然后在方法combineInfo
中你又有了几个必须做同样的构造函数。
您可以通过在构造后提示提示数据的方法来避免此问题。如果您显示可能有用的构造函数代码。
话虽如此,这种方法很可能应该是:
void Info::combineInfo(const Info& p1)
{
name = p1.name; // Why not keep p2.name?
hours += p1.hours;
total += p1.total;
}
然后致电:
printInfo(p2);