[英]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 */
准確地將信息放入p1
和p2
因為我可以用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
對象( p1
和p2
)中的信息。
更好的解決方案是讓構造函數通過參數接收數據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
的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);
你可以寫:
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.