簡體   English   中英

c ++類成員函數

[英]c++ classes member functions

使用以下代碼,在類中聲明成員函數,它會提示用戶輸入各種輸入,如小時和付費。

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();打印出來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);
}

您沒有顯示它,但您可能要求Info構造函數中的輸入。 就像是:

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

因此,在combineInfo中,您可以創建兩個Info類對象,因此構造函數會運行並請求每個對象的輸入。 只是不要求構造函數中的值。 添加另一個方法AskForInput來詢問值,不要從構造函數中調用它。

我猜你正在讀取你的構造函數中的stdin輸入信息(你可以發布這段代碼嗎?)。 因此,當你再次創建p2和pnew時,它會調用相同的代碼。

我建議你有單獨的代碼用於使用stdin而不是你的構造函數初始化變量。 否則,你在這里打電話的時間並不多!

由於我最后輸入了很多評論,我將它組合成一個答案:

根據其他答案,您的問題是您在combineInfo函數中調用Info的構造函數,並且您在combineInfo函數中提示用戶。 在構造函數中使用std::cin通常是一個壞主意 - 如果你(或你的代碼的用戶)決定在std::cin不合適的情況下使用代碼怎么辦(例如,當你后來決定升級到GUI時)? 如果要使用預定數據構造對象,該怎么辦? 或者在單元測試中?

實際上,您自己的代碼提供了這樣一個示例:您已經定義了Info ,其唯一的方法是通過向用戶請求信息來構建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;
}

似乎只適合你,因為構造函數問題 - 你被提示輸入combineInfop2 ,所以它最終與你實際打算使用的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;
}

在這種情況下, hourstotalthis.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

大概你已經決定在值中讀取Info的默認構造函數。 然后在方法combineInfo你又有了幾個必須做同樣的構造函數。

您可以通過在構造之后使用提示輸入數據的方法來避免此問題。 如果您顯示可能有用的構造函數代碼。

話雖如此,該方法很可能應該是:

void Info::combineInfo(const Info& p1)
{
    name = p1.name; // Why not keep p2.name?
    hours += p1.hours;
    total += p1.total;
}

然后打電話:

printInfo(p2);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM