c ++类成员函数

时间:2013-03-13 03:46:03

标签: c++

使用以下代码,在类中声明成员函数,它会提示用户输入各种输入,如小时和付费。

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  */

信息准确地放入p1p2,因为我可以使用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 个答案:

答案 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对象(p1p2)内。

更好的解决方案是让构造函数通过参数 - 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
在这种情况下,

p2Info 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; } hourstotal的简写。

要考虑将来参考的另一件事是重载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);