Projects@高階程式設計課程期末作業
(提醒:本人並非計算機專業學生,程式設計能力也不算強,此程式僅供參考學習,有缺點或問題可提出。)
大一下學期高階程式設計期末作業:使用C++設計一個高校職工工資管理系統。
問題背景:
大學主要有4類人員:教師、行政人員、後勤人員、學院院長。現需使用C++設計一個高校職工工資管理系統,以管理各職工的工資分配。
題目要求:
整個系統在設計過程中要充分體現出面向物件的三個基本特徵(封裝,繼承,多型)。
要求職工類基本資訊有職工號、姓名、月基本工資、年齡、性別、類別等(根據需要新增或刪除)。
教師:職稱,課酬標準(每課時),本月上課數(課時)
行政人員:職級,月獎金
後勤人員:崗位,月補貼
院長:學院名稱,課酬和月獎金(繼承父類),額外獎勵
月工資的計算方法:
A、教師:基本月薪講師為5000元,副教授乘以1。5係數,正教授乘以2係數;加上課酬(課酬標準*月上課數)
B、行政人員:基本月薪普通科員4000,處級幹部7000;加上月度獎金
C、後勤人員:基本月薪3000;加上月度補貼
D、院長:基本月薪+課酬+月底獎金+月底額外獎勵
選單模組設定:
① 職工資料錄入建檔:
教師:職工號,姓名,職稱
行政人員:職工號,姓名,職級(科員,處長)
後勤人員:職工號,姓名,崗位
院長:職工號,姓名,學院名稱
② 月度工資發放
教師:輸入本月上課課時
行政人員:輸入本月月度獎金
後勤人員:輸入本月月度補貼
院長:輸入本月課時數,月度獎金,月度額外獎勵
③ 查詢職工基本情況和月工資:輸入職工號查詢
(增加職工,刪除職工)
④ 資料統計:輸出月度高校員工工資表
⑤ 退出本系統;
(其他功能根據自己能力可以新增)
C++程式碼:
/*高階程式設計期末專案設計
專案名稱:高校職工工資管理系統
程式基本功能:輸入職工的課時、獎金、補貼等資料,可按照職工號查詢其基本資料,
按照職工號增加或刪除職工資料,最終輸出月度工資表。
額外功能:可將讀取txt檔案中職工資料的存檔,也可將職工資料存檔到txt檔案中。
注意:若有職工資料存檔,請將其存放在本程式所在資料夾裡面的Person File。txt檔案裡,
可自行編輯,確保文字按照如下格式編寫或儲存並放在與此原始碼檔案同一目錄之下:
職工崗位用1代表教師,2代表行政人員,3代表後勤人員,4代表院長。
(教師) (行政人員) (後勤人員) (院長)
1 2 3 4
【姓名】 【姓名】 【姓名】 【姓名】
【職工號】 【職工號】 【職工號】 【職工號】
【性別】 【性別】 【性別】 【性別】
【年齡】 【年齡】 【年齡】 【年齡】
【職稱】 【職稱】 【職位】 【學院名稱】
如:
高校職工工資管理系統資料存檔
1
張三
123
女
55
講師
2
李四
456
男
60
科員
3
王五
789
男
34
保衛處
4
趙六
321
女
48
微電子科學與技術學院
。。。*/
#include
#include
#include
#include
#define lessonbonus 200
//設定每一節課的課酬是200元。
using
namespace
std
;
class
Person
//基類Person,定義了所有職工的基本資料如姓名、年齡等。
{
public
:
int
number
,
age
,
salary
;
string
name
,
sex
,
type
;
void
setting
(
string
utype
,
string
uname
,
int
unumber
,
string
usex
,
int
uage
)
//基類初始化函式。
{
number
=
unumber
;
age
=
uage
;
name
=
uname
;
sex
=
usex
;
type
=
utype
;
}
};
class
Teacher
:
virtual
public
Person
//派生類Teacher,virtual繼承基類Person的成員。
{
protected
:
//重要資料歸在protected下。
string
title1
;
int
period
;
//定義教師特有的資料成員職稱和課時。
public
:
void
settingt
(
int
unumber
,
int
uage
,
string
uname
,
string
usex
,
string
utype
,
string
utitle1
)
//Teacher類的初始化函式。
{
setting
(
utype
,
uname
,
unumber
,
usex
,
uage
);
title1
=
utitle1
;
}
void
enteringt
(
void
)
//Teacher類的手動輸入初始化函式。
{
type
=
“教師”
;
cout
<<
“請輸入該教師的姓名(如:張三):”
<<
endl
;
cin
>>
name
;
cout
<<
“請輸入該教師的職工號(如:123456):”
<<
endl
;
cin
>>
number
;
cout
<<
“請輸入該教師的性別(如:女):”
<<
endl
;
cin
>>
sex
;
cout
<<
“請輸入該教師的年齡(如:35):”
<<
endl
;
cin
>>
age
;
cout
<<
“請輸入該教師的職稱(如:講師):”
<<
endl
;
cin
>>
title1
;
}
void
Writingt
()
//Teacher類的資料儲存函式。
{
ofstream
in
;
in
。
open
(
“Person File。txt”
,
ios
::
app
);
//在txt檔案的最後新增上指定成員的各項資訊。
in
<<
“
\n
”
<<
“1”
<<
“
\n
”
<<
name
<<
“
\n
”
<<
number
<<
“
\n
”
<<
sex
<<
“
\n
”
<<
age
<<
“
\n
”
<<
title1
;
in
。
close
();
}
void
enteringperiod
()
//Teacher類的課時數輸入函式。
{
cout
<<
“請輸入”
<<
name
<<
“的課時數(如:15)”
<<
endl
;
cin
>>
period
;
if
(
title1
==
“講師”
)
{
salary
=
5000
+
lessonbonus
*
period
;
}
if
(
title1
==
“副教授”
)
{
salary
=
7500
+
lessonbonus
*
period
;
}
if
(
title1
==
“教授”
)
{
salary
=
10000
+
lessonbonus
*
period
;
//對不同職稱的教師分別發放工資。
}
}
void
displayt
()
//Teacher類的展示函式。
{
cout
<<
number
<<
“
\t
”
<<
name
<<
“
\t
”
<<
“教師”
<<
“
\t
”
<<
title1
<<
“
\t
”
<<
salary
<<
endl
;
}
void
enteringt
(
int
g
)
//Teacher類的根據職工號手動新增資料函式。
{
int
elect
;
type
=
“教師”
;
cout
<<
“請輸入該教師的姓名(如:張三):”
<<
endl
;
cin
>>
name
;
number
=
g
;
cout
<<
“請輸入該教師的性別(如:女):”
<<
endl
;
cin
>>
sex
;
cout
<<
“請輸入該教師的年齡(如:35):”
<<
endl
;
cin
>>
age
;
cout
<<
“請輸入該教師的職稱(如:講師):”
<<
endl
;
cin
>>
title1
;
enteringperiod
();
cout
<<
“若要將此新增職工資料存入Person File。txt中請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
if
(
elect
)
Writingt
();
}
int
returningsalaryt
()
//Teacher類的返回工資函式。
{
return
salary
;
}
};
class
Official
:
virtual
public
Person
//派生類Official,virtual繼承基類Person的成員。
{
protected
:
//重要資料歸在protected下。
string
title2
;
int
bonus
;
//定義行政人員特有的資料成員職稱和獎金。
public
:
void
settingo
(
int
unumber
,
int
uage
,
string
uname
,
string
usex
,
string
utype
,
string
utitle2
)
//Official類的初始化函式。
{
setting
(
utype
,
uname
,
unumber
,
usex
,
uage
);
title2
=
utitle2
;
}
void
enteringo
(
void
)
//Official類的手動輸入初始化函式。
{
type
=
“行政人員”
;
cout
<<
“請輸入該行政人員的姓名(如:張三):”
<<
endl
;
cin
>>
name
;
cout
<<
“請輸入該行政人員的職工號(如:123456):”
<<
endl
;
cin
>>
number
;
cout
<<
“請輸入該行政人員的性別(如:女):”
<<
endl
;
cin
>>
sex
;
cout
<<
“請輸入該行政人員的年齡(如:35):”
<<
endl
;
cin
>>
age
;
cout
<<
“請輸入該行政人員的職稱(如:科員):”
<<
endl
;
cin
>>
title2
;
}
void
Writingo
()
//Official類的資料儲存函式。
{
ofstream
in
;
in
。
open
(
“Person File。txt”
,
ios
::
app
);
//在txt檔案的最後新增上指定成員的各項資訊。
in
<<
“
\n
”
<<
“2”
<<
“
\n
”
<<
name
<<
“
\n
”
<<
number
<<
“
\n
”
<<
sex
<<
“
\n
”
<<
age
<<
“
\n
”
<<
title2
;
in
。
close
();
}
void
enteringbonus
()
//Official類的獎金輸入函式。
{
cout
<<
“請輸入”
<<
name
<<
“的獎金(如:3000)”
<<
endl
;
cin
>>
bonus
;
if
(
title2
==
“科員”
)
{
salary
=
4000
+
bonus
;
}
if
(
title2
==
“處級幹部”
)
{
salary
=
7000
+
bonus
;
//對不同職稱的行政人員分別發放工資。
}
}
void
displayo
()
//Official類的展示函式。
{
cout
<<
number
<<
“
\t
”
<<
name
<<
“
\t
”
<<
“行政”
<<
“
\t
”
<<
title2
<<
“
\t
”
<<
salary
<<
endl
;
}
void
enteringo
(
int
a
)
//Official類的根據職工號手動新增資料函式。
{
int
elect
;
type
=
“行政人員”
;
cout
<<
“請輸入該行政人員的姓名(如:張三):”
<<
endl
;
cin
>>
name
;
number
=
a
;
cout
<<
“請輸入該行政人員的性別(如:女):”
<<
endl
;
cin
>>
sex
;
cout
<<
“請輸入該行政人員的年齡(如:35):”
<<
endl
;
cin
>>
age
;
cout
<<
“請輸入該行政人員的職稱(如:科員):”
<<
endl
;
cin
>>
title2
;
enteringbonus
();
cout
<<
“若要將此新增職工資料存入Person File。txt中請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
if
(
elect
)
Writingo
();
}
int
returningsalaryo
()
//Official類的返回工資函式。
{
return
salary
;
}
};
class
Logistical
:
public
Person
//派生類Logistical,繼承基類Person的成員。
{
protected
:
//重要資料歸在protected下。
string
title3
;
int
remedy
;
//定義後勤人員特有的資料成員職位和補貼。
public
:
void
settingl
(
int
unumber
,
int
uage
,
string
uname
,
string
usex
,
string
utype
,
string
utitle3
)
//Logistical類的初始化函式。
{
setting
(
utype
,
uname
,
unumber
,
usex
,
uage
);
title3
=
utitle3
;
}
void
enteringl
(
void
)
//Logistical類的手動輸入初始化函式。
{
type
=
“後勤人員”
;
cout
<<
“請輸入該後勤人員的姓名(如:張三):”
<<
endl
;
cin
>>
name
;
cout
<<
“請輸入該後勤人員的職工號(如:123456):”
<<
endl
;
cin
>>
number
;
cout
<<
“請輸入該後勤人員的性別(如:女):”
<<
endl
;
cin
>>
sex
;
cout
<<
“請輸入該後勤人員的年齡(如:35):”
<<
endl
;
cin
>>
age
;
cout
<<
“請輸入該後勤人員的職位(如:保衛處):”
<<
endl
;
cin
>>
title3
;
}
void
Writingl
()
//Logistical類的資料儲存函式。
{
ofstream
in
;
in
。
open
(
“Person File。txt”
,
ios
::
app
);
//在txt檔案的最後新增上指定成員的各項資訊。
in
<<
“
\n
”
<<
“3”
<<
“
\n
”
<<
name
<<
“
\n
”
<<
number
<<
“
\n
”
<<
sex
<<
“
\n
”
<<
age
<<
“
\n
”
<<
title3
;
in
。
close
();
}
void
enteringremedy
()
//Logistical類的補貼輸入函式。
{
cout
<<
“請輸入”
<<
name
<<
“的補貼(如:2000)”
<<
endl
;
cin
>>
remedy
;
salary
=
3000
+
remedy
;
}
void
displayl
()
//Logistical類的展示函式。
{
cout
<<
number
<<
“
\t
”
<<
name
<<
“
\t
”
<<
“後勤”
<<
“
\t
”
<<
title3
<<
“
\t
”
<<
salary
<<
endl
;
}
void
enteringl
(
int
a
)
//Logistical類的根據職工號手動新增資料函式。
{
int
elect
;
type
=
“後勤人員”
;
cout
<<
“請輸入該後勤人員的姓名(如:張三):”
<<
endl
;
cin
>>
name
;
number
=
a
;
cout
<<
“請輸入該後勤人員的性別(如:女):”
<<
endl
;
cin
>>
sex
;
cout
<<
“請輸入該後勤人員的年齡(如:35):”
<<
endl
;
cin
>>
age
;
cout
<<
“請輸入該後勤人員的職位(如:保衛處):”
<<
endl
;
cin
>>
title3
;
enteringremedy
();
cout
<<
“若要將此新增職工資料存入Person File。txt中請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
if
(
elect
)
Writingl
();
}
int
returningsalaryl
()
//Logistical類的返回工資函式。
{
return
salary
;
}
};
class
Principal
:
public
Teacher
,
public
Official
//派生類Principal,繼承基類Teacher和Official的成員。
{
protected
:
//重要資料歸在protected下。
string
school_name
;
int
extra_bonus
;
//定義院長特有的資料成員學院名稱和額外獎勵。
public
:
void
settingp
(
int
unumber
,
int
uage
,
string
uname
,
string
usex
,
string
utype
,
string
utitle1
,
string
utitle2
,
string
uschool_name
)
//Principal類的初始化函式。
{
setting
(
utype
,
uname
,
unumber
,
usex
,
uage
);
title1
=
utitle1
;
title2
=
utitle2
;
school_name
=
uschool_name
;
}
void
enteringp
(
void
)
//Principal類的手動輸入初始化函式。
{
type
=
“院長”
;
title1
=
“教授”
;
title2
=
“學院院長”
;
cout
<<
“請輸入該院長的姓名(如:張三):”
<<
endl
;
cin
>>
name
;
cout
<<
“請輸入該院長的職工號(如:123456):”
<<
endl
;
cin
>>
number
;
cout
<<
“請輸入該院長的性別(如:女):”
<<
endl
;
cin
>>
sex
;
cout
<<
“請輸入該院長所屬的學院名稱(如:微電子科學與技術學院):”
<<
endl
;
cin
>>
school_name
;
cout
<<
“請輸入該院長的年齡(如:35):”
<<
endl
;
cin
>>
age
;
}
void
Writingp
()
//Principal類的資料儲存函式。
{
ofstream
in
;
in
。
open
(
“Person File。txt”
,
ios
::
app
);
//在txt檔案的最後新增上指定成員的各項資訊。
in
<<
“
\n
”
<<
“4”
<<
“
\n
”
<<
name
<<
“
\n
”
<<
number
<<
“
\n
”
<<
sex
<<
“
\n
”
<<
age
<<
“
\n
”
<<
school_name
;
in
。
close
();
}
void
enteringpp
()
//Principal類的課時數、獎金和額外獎勵輸入函式。
{
cout
<<
“請輸入”
<<
name
<<
“的課時數(如:15)”
<<
endl
;
cin
>>
period
;
cout
<<
“請輸入”
<<
name
<<
“的獎金(如:3000)”
<<
endl
;
cin
>>
bonus
;
cout
<<
“請輸入”
<<
name
<<
“的額外獎勵(如:2000)”
<<
endl
;
cin
>>
extra_bonus
;
salary
=
10000
+
lessonbonus
*
period
+
bonus
+
extra_bonus
;
}
void
displayp
()
//Principal類的展示函式。
{
cout
<<
number
<<
“
\t
”
<<
name
<<
“
\t
”
<<
“院長”
<<
“
\t
”
<<
“教授”
<<
“
\t
”
<<
salary
<<
endl
;
}
void
enteringp
(
int
a
)
//Principal類的根據職工號手動新增資料函式。
{
int
elect
;
type
=
“院長”
;
title1
=
“教授”
;
title2
=
“學院院長”
;
cout
<<
“請輸入該院長的姓名(如:張三):”
<<
endl
;
cin
>>
name
;
number
=
a
;
cout
<<
“請輸入該院長的性別(如:女):”
<<
endl
;
cin
>>
sex
;
cout
<<
“請輸入該院長所屬的學院名稱(如:微電子科學與技術學院):”
<<
endl
;
cin
>>
school_name
;
cout
<<
“請輸入該院長的年齡(如:35):”
<<
endl
;
cin
>>
age
;
enteringpp
();
cout
<<
“若要將此新增職工資料存入Person File。txt中請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
if
(
elect
)
Writingp
();
}
int
returningsalaryp
()
//Principal類的返回工資函式。
{
return
salary
;
}
};
int
Counting
(
char
*
filename
)
//輸出txt檔案中行數的函式,須輸入對應檔名稱指標。
{
ifstream
ReadFile
;
int
n
=
0
;
string
tmp
;
ReadFile
。
open
(
filename
,
ios
::
in
);
//開啟txt檔案。
while
(
getline
(
ReadFile
,
tmp
,
‘\n’
))
{
n
++
;}
//行數疊加。
ReadFile
。
close
();
//關閉txt檔案。
return
n
;
//返回行數。
}
string
Reading
(
char
*
filename
,
int
line
)
//讀取txt檔案某一行中資料的函式,須輸入對應檔名稱指標和指定行數。
{
int
lines
,
i
=
0
;
string
temp
;
fstream
file
;
file
。
open
(
filename
,
ios
::
in
);
//開啟txt檔案。
lines
=
Counting
(
“Person File。txt”
);
while
(
getline
(
file
,
temp
)
&&
i
<
line
-
1
)
{
i
++
;
}
file
。
close
();
//關閉txt檔案。
return
temp
;
}
int
main
(
void
)
//主函式。
{
Teacher
*
pt
=
new
Teacher
[
100
];
Official
*
po
=
new
Official
[
100
];
Logistical
*
pl
=
new
Logistical
[
100
];
Principal
*
pp
=
new
Principal
[
100
];
//使用指標動態建立四種職工型別的物件陣列,並於主函式末尾釋放記憶體。
int
b
,
c
,
i
,
j
,
elect
,
PersonsInMemory
,
ct
=
0
,
co
=
0
,
cl
=
0
,
cp
=
0
;
int
Number
,
Age
,
Type
,
total_salary
=
0
;
string
Name
,
Sex
,
a
,
d
;
string
linedata
;
//定義各種要用到的資料。
cout
<<
“高校職工工資管理系統C++程式”
<<
endl
<<
endl
<<
“(1)職工資料錄入建檔”
<<
endl
;
//第一部分:錄入。
cout
<<
“若要輸入新的職工資料,請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
while
(
elect
)
//手動錄入過程中呼叫各物件的手動輸入函式。
{
cout
<<
“請輸入職工的崗位,教師請輸入1,行政人員請輸入2,後勤人員請輸入3,院長請輸入4:”
<<
endl
;
cin
>>
Type
;
if
(
Type
==
1
)
{
pt
[
ct
]。
enteringt
();
ct
=
ct
+
1
;
}
else
if
(
Type
==
2
)
{
po
[
co
]。
enteringo
();
co
=
co
+
1
;
}
else
if
(
Type
==
3
)
{
pl
[
cl
]。
enteringl
();
cl
=
cl
+
1
;
}
else
{
pp
[
cp
]。
enteringp
();
cp
=
cp
+
1
;
}
cout
<<
“若要繼續輸入新的職工資料,請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
}
cout
<<
“若要呼叫Person File。txt中職工資料存檔,請確保資料按照正確的格式儲存並輸入1,否則輸入0。”
<<
endl
;
cin
>>
elect
;
if
(
elect
)
//由存檔txt檔案匯入職工資料。
{
PersonsInMemory
=
(
Counting
(
“Person File。txt”
)
-
1
)
/
6
;
for
(
i
=
0
;
i
<
PersonsInMemory
;
i
++
)
{
Type
=
atoi
(
Reading
(
“Person File。txt”
,
6
*
i
+
2
)。
c_str
());
//第一行:型別,使用atio將string型別資料轉換為int型別。
Name
=
Reading
(
“Person File。txt”
,
6
*
i
+
3
);
//第二行:姓名。
Number
=
atoi
(
Reading
(
“Person File。txt”
,
6
*
i
+
4
)。
c_str
());
//第三行:職工號,使用atio將string型別資料轉換為int型別。
Sex
=
Reading
(
“Person File。txt”
,
6
*
i
+
5
);
//第四行:性別。
Age
=
atoi
(
Reading
(
“Person File。txt”
,
6
*
i
+
6
)。
c_str
());
//第五行:年齡,使用atio將string型別資料轉換為int型別。
a
=
Reading
(
“Person File。txt”
,
6
*
i
+
7
);
//第六行:特定資訊。
if
(
Type
==
1
)
{
pt
[
ct
]。
settingt
(
Number
,
Age
,
Name
,
Sex
,
“教師”
,
a
);
//將資料返回給各類的自動初始化函式。
ct
=
ct
+
1
;
}
else
if
(
Type
==
2
)
{
po
[
co
]。
settingo
(
Number
,
Age
,
Name
,
Sex
,
“行政人員”
,
a
);
co
=
co
+
1
;
}
else
if
(
Type
==
3
)
{
pl
[
cl
]。
settingl
(
Number
,
Age
,
Name
,
Sex
,
“後勤人員”
,
a
);
cl
=
cl
+
1
;
}
else
{
pp
[
cp
]。
settingp
(
Number
,
Age
,
Name
,
Sex
,
“院長”
,
“教授”
,
“學院院長”
,
d
);
cp
=
cp
+
1
;
}
}
}
cout
<<
“若要將本次執行程式 所有的! 職工資料存入Person File。txt中,請輸入1,否則輸入0。”
<<
endl
;
cin
>>
elect
;
if
(
elect
)
//可將職工資料存入txt檔案中,以便下次呼叫。
{
cout
<<
“若要抹去原有資料,請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
if
(
elect
)
{
fstream
file
(
“Person File。txt”
,
ios
::
out
);}
//抹去txt檔案原有資料。
for
(
i
=
0
;
i
<
ct
;
i
++
)
{
pt
[
i
]。
Writingt
();
}
for
(
i
=
0
;
i
<
co
;
i
++
)
{
po
[
i
]。
Writingo
();
}
for
(
i
=
0
;
i
<
cl
;
i
++
)
{
pl
[
i
]。
Writingl
();
}
for
(
i
=
0
;
i
<
cp
;
i
++
)
{
pp
[
i
]。
Writingp
();
}
}
cout
<<
endl
<<
“(2)月度工資發放”
<<
endl
;
//第二部分:根據輸入的每個職工的資料計算工資。
for
(
i
=
0
;
i
<
ct
;
i
++
)
{
pt
[
i
]。
enteringperiod
();
}
for
(
i
=
0
;
i
<
co
;
i
++
)
{
po
[
i
]。
enteringbonus
();
}
for
(
i
=
0
;
i
<
cl
;
i
++
)
{
pl
[
i
]。
enteringremedy
();
}
for
(
i
=
0
;
i
<
cp
;
i
++
)
{
pp
[
i
]。
enteringpp
();
}
cout
<<
endl
<<
“(3)查詢職工基本情況和月工資:”
<<
endl
;
//第三部分:按照輸入的職工號查詢職工資料,可選擇刪除或者新增。
cout
<<
“若要輸入職工號查詢職工基本情況和月工資,請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
while
(
elect
)
{
c
=
0
;
cout
<<
“請輸入職工號:”
<<
endl
;
cin
>>
b
;
for
(
i
=
0
;
i
<
ct
;
i
++
)
{
if
(
pt
[
i
]。
number
==
b
)
{
cout
<<
“職工號
\t
姓名
\t
類別
\t
職位
\t
月工資”
<<
endl
;
pt
[
i
]。
displayt
();
c
=
c
+
1
;
cout
<<
“若要刪除該職工號對應的職工資料,請輸入1,否則輸入0:”
<<
endl
;
//可刪除對應的職工資料,使用將物件陣列平移的方式刪除某一物件。
cin
>>
elect
;
if
(
elect
)
{
for
(
j
=
i
;
j
<=
ct
;
j
++
)
{
pt
[
j
]
=
pt
[
j
+
1
];}
ct
=
ct
-
1
;
}
}
}
for
(
i
=
0
;
i
<
co
;
i
++
)
{
if
(
po
[
i
]。
number
==
b
)
{
cout
<<
“職工號
\t
姓名
\t
類別
\t
職位
\t
月工資”
<<
endl
;
po
[
i
]。
displayo
();
c
=
c
+
1
;
cout
<<
“若要刪除該職工號對應的職工資料,請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
if
(
elect
)
{
for
(
j
=
i
;
j
<=
co
;
j
++
)
{
po
[
j
]
=
po
[
j
+
1
];}
co
=
co
-
1
;
}
}
}
for
(
i
=
0
;
i
<
cl
;
i
++
)
{
if
(
pl
[
i
]。
number
==
b
)
{
cout
<<
“職工號
\t
姓名
\t
類別
\t
職位
\t
月工資”
<<
endl
;
pl
[
i
]。
displayl
();
c
=
c
+
1
;
cout
<<
“若要刪除該職工號對應的職工資料,請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
if
(
elect
)
{
for
(
j
=
i
;
j
<=
cl
;
j
++
)
{
pl
[
j
]
=
pl
[
j
+
1
];}
cl
=
cl
-
1
;
}
}
}
for
(
i
=
0
;
i
<
cp
;
i
++
)
{
if
(
pp
[
i
]。
number
==
b
)
{
cout
<<
“職工號
\t
姓名
\t
類別
\t
職位
\t
月工資”
<<
endl
;
pp
[
i
]。
displayp
();
c
=
c
+
1
;
cout
<<
“若要刪除該職工號對應的職工資料,請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
if
(
elect
)
{
for
(
j
=
i
;
j
<=
cp
;
j
++
)
{
pp
[
j
]
=
pp
[
j
+
1
];}
cp
=
cp
-
1
;
}
}
}
if
(
c
==
0
)
{
cout
<<
“沒有找到該職工號對應的職工資料,若要以此職工號新增職工資料,請輸入1,否則輸入0:”
<<
endl
;
//沒有找到資料則可以以此職工號新增職工資料。
cin
>>
elect
;
if
(
elect
)
{
cout
<<
“請輸入職工的崗位,教師請輸入1,行政人員請輸入2,後勤人員請輸入3,院長請輸入4:”
<<
endl
;
//呼叫各類的手動輸入資料函式新增職工資料。
cin
>>
Type
;
if
(
Type
==
1
)
{
pt
[
ct
]。
enteringt
(
b
);
ct
=
ct
+
1
;
}
else
if
(
Type
==
2
)
{
po
[
co
]。
enteringo
(
b
);
co
=
co
+
1
;
}
else
if
(
Type
==
3
)
{
pl
[
cl
]。
enteringl
(
b
);
cl
=
cl
+
1
;
}
else
{
pp
[
cp
]。
enteringp
(
b
);
cp
=
cp
+
1
;
}
}
}
cout
<<
“若要繼續輸入職工號查詢職工基本情況和月工資,請輸入1,否則輸入0:”
<<
endl
;
cin
>>
elect
;
}
cout
<<
endl
<<
“(4)資料統計”
<<
endl
;
//第四部分:資料統計。
cout
<<
“——————————————————————”
<<
endl
;
cout
<<
“職工號
\t
姓名
\t
類別
\t
職位
\t
月工資
\n
——————————————————————”
<<
endl
;
for
(
i
=
0
;
i
<
ct
;
i
++
)
{
pt
[
i
]。
displayt
();
total_salary
=
total_salary
+
pt
[
i
]。
returningsalaryt
();
//計算總工資。
}
for
(
i
=
0
;
i
<
co
;
i
++
)
{
po
[
i
]。
displayo
();
total_salary
=
total_salary
+
po
[
i
]。
returningsalaryo
();
}
for
(
i
=
0
;
i
<
cl
;
i
++
)
{
pl
[
i
]。
displayl
();
total_salary
=
total_salary
+
pl
[
i
]。
returningsalaryl
();
}
for
(
i
=
0
;
i
<
cp
;
i
++
)
{
pp
[
i
]。
displayp
();
total_salary
=
total_salary
+
pp
[
i
]。
returningsalaryp
();
}
cout
<<
“——————————————————————
\n
合計: ”
<<
total_salary
<<
endl
;
//輸出合計工資。
cout
<<
“平均工資: ”
<<
total_salary
/
(
ct
+
co
+
cl
+
cp
)
<<
endl
;
//輸出平均工資。
cout
<<
“
\n
退出本系統”
<<
endl
;
delete
[]
pt
;
delete
[]
po
;
delete
[]
pl
;
delete
[]
pp
;
//最後釋放動態物件陣列的記憶體。
}
程式功能:
基本功能有輸入職工的課時、獎金、補貼等資料,可按照職工號查詢其基本資料,按照職工號增加或刪除職工資料,最終輸出月度工資表。
執行結果示例:
圖1 執行結果示例
程式特點:
程式很好地體現了封裝、繼承和多型的面向物件的三個基本特徵。
封裝性體現在對各物件中的資料成員使用了protected宣告,避免類外訪問或修改資料成員;此外,執行過程中所需的函式(方法)如Counting、Reading等封裝在外,確保封裝性的同時提高易讀性。
繼承性首先體現在Teacher、Official、Logistical和Principal類繼承Person類中,Person類有職工的基本資訊,而各派生類中有此型別職工的獨有資料;其次,由於院長同時作為教師和行政人員,因此Teacher類和Official類均是Principal類的虛基類,避免了多重繼承時對記憶體空間的盲目分配。
多型性則體現在Teacher、Official、Logistical和Principal類中有一對同名但形參表不同的函式實現了函式過載(enteringt函式、enteringo函式、enteringl函式、enteringp函式),他們能被分別正確呼叫,是因為面向物件的多型性這個特徵允許以不同的形參表來呼叫函式名相同的函式,體現了靜態多型性。
除了能完成要求的基本功能外,根據我個人的程式設計能力和執行程式時的實際情況,我額外為之添加了儲存職工資料的功能:將資料儲存在同目錄下的一個txt檔案中。首先我思考了儲存職工資料的必要性:可以避免每次執行程式時都要重新輸入每個職工的資料,大大提升實際的工作效率和可持續性。而選擇txt檔案的原因有二:一是資料存放在txt檔案中可在程式外檢視資料,並可清晰明瞭地顯示出來,不必執行程式才可以看到資料,方便平時的調查;二是可在程式外手動增刪資料,不必留在程式中操作,提高了程式執行時的效率。
遇到的困難及解決方法:
首先是讀取txt檔案資料和寫入資料到txt檔案中。我先是學習了檔案讀寫的方法,然後將職工中通用的資料設為6個,在txt檔案中體現為每個一行。讀取時按行讀取,寫入時按行寫入即可。
然後就是增刪職工資料的問題。我先是想用delete刪除指標對應陣列元素的方法,但是動態記憶體分配中不清楚指標的操作,並且delete和new必須一一對應,若要刪除只能刪除整個物件陣列。經歷幾次失敗後,我決定使用平移陣列的方法。這樣不僅不會影響到陣列後面的元素,程式編寫和閱讀起來也很直觀。
其他的各種小問題也很多,篇幅有限,解決過程也不再提及。
Thanks for your reading。