0

使用下面的代码,在类中声明成员函数,它提示用户输入各种输入,如小时和工资。

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

4 回答 4

1

您没有显示它,但您可能在 Info 构造函数中要求输入。就像是:

Info::Info()
{
   cout << "Enter name: ";
   cin >> name;
   cout << "Enter hours: ";
   cin >> hours;
   cout << "Enter total: ";
   cin >> total;
}

因此,在 combineInfo 中,您创建了 Info 类的两个对象,因此构造函数运行并要求每个对象输入。只是不要询问构造函数中的值。添加另一个方法 AskForInput 来询问值,而不是从构造函数中调用它。

于 2013-03-13T03:54:51.077 回答
1

我猜你正在从你的构造函数中读取来自 stdin 的输入信息(你能发布这段代码吗?)。因此,当您再次创建 p2 和 pnew 时,它调用的是相同的代码。

我建议你有单独的代码来用标准输入初始化变量,而不是你的构造函数。否则,关于它被调用,你无能为力!

于 2013-03-13T03:55:17.913 回答
0

由于我最终输入了很多评论,因此我将其合并为一个答案:

根据其他答案,您的问题是您Info在函数中调用构造combineInfo函数,并且在构造函数中提示用户。在构造函数中使用通常是个坏主意std::cin- 如果您(或您的代码的用户)决定在std::cin不合适的情况下使用代码(例如,当您后来决定升级到 GUI 时)怎么办?如果你想用预先确定的数据构造对象怎么办?还是在单元测试中?

事实上,您自己的代码提供了这样一个示例:您已经定义Info了一种方式,即构建它的唯一方式是向用户询问信息。但是,您有两种实际想要构造对象的方法 - (1) 通过提示用户输入信息,以及 (2) 通过组合已经存在于其他两个Info对象 (p1p2) 中的信息。

更好的解决方案是让构造函数通过参数 - 接收数据Info::Info(string name, int hours, int total),从类外的用户获取信息(适当时),并将其传递给构造函数。

或者,如果您决定将cin代码保留在构造函数中,则不要使用compareInfo()函数 - 创建第二个构造函数,它将两个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对象:

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

你有我能想到的三个解决方案,没有一个特别有吸引力(我很惊讶老师会把这个要求强加给你):

(1) 提供一个不提示输入信息的构造函数。但是,它必须具有与请求信息的签名不同的签名,因为您不能两次定义默认构造函数:

Info::Info()
{
   // Prompt user.
}

Info::Info(int dummyValue)
{
   // Do nothing.
}

然后,当您创建pnew对象时,调用第二个构造函数:Info pnew(0);.

(2) 根本不提供默认构造函数,而是创建一个您告知是否提示的构造函数:

Info::Info(bool prompt)
{
    if (prompt)
    {
        // Construct object by prompting user.
    }
    // No need to do an else, simply do nothing if !prompt
}

这样做的缺点是您必须始终提供一个参数来构造 Info 对象:

Info p1; // Error, no default constructor
Info p1(true); // Construct by prompting
Info pnew(false); // Construct without prompting

(3)根本不要创建临时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;
}

由于构造函数问题,这似乎只对您正常工作 - 系统会提示您输入combineInfo's的信息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在这种情况下,是 and的total简写。this.hoursthis.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);

你可以写:

Info pnew = p1 + p2;

最后,考虑通过引用而不是值传递 - 对于非平凡的对象,函数取消引用地址而不是制作它的新副本通常更快:

Info Info::combineInfo(const Info& p1); // p1 passed by reference
                                        // const replicates the behaviour
                                        // of pass by value whereby
                                        // you cannot accidentally modify
                                        // the original object.

编辑:但是如果您使用上面的解决方案 3,请不要这样做,否则您将修改您p1可能不希望的原始文件。

于 2013-03-13T03:54:18.267 回答
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);
于 2013-03-13T03:55:30.903 回答