C++ - 正确访问联合中的嵌套结构
C++ - Properly accessing nested struct in union
我正在为学校做一个项目,需要建立这种代码结构并使其正常工作。
问题: 我需要正确访问联合成员(h 和 s),而不是获取随机的内存数据块——实际上取回我存储的数字。我确实理解联合是如何工作的,所以我很困惑为什么我的代码给我随机数据而不是我存储在那里的数字。
注意:我确实在寻找这个问题的其他答案(因为这听起来像是一个很常见的语法问题),但其他解决方案并不真正适合我的情况。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
struct worker {
enum kind {NOTSALARIED, ISSALRIED};
bool isSalaried;
union {
struct hourly{
double numberHours;
double hourlyRate;
} h; // end of 'hourly' struct
struct salaried{
double salaryAmount;
double bonusAmount;
} s; // end of 'salaried' struct
} info; // end of 'info' union
};
/// PROTOTYPE section
worker* getHourly();
worker* getSalaried();
void printWorker(worker);
int main() {
worker *theWorker; // avoids making another 'worker' object for no reason
// format code for 'double' values
cout << fixed << showpoint << setprecision(2);
// used string so avoid user entering name with the correct first character
string choice;
cout << "(H)ourly or (S)alary? ";
getline(cin, choice);
/// LOGIC SECTION: Checks what the user entered
if(choice == "H" || choice == "h") {
// get the salary
theWorker = getHourly();
// pass in the dereferenced pointer to print out the info
printWorker(*theWorker);
}
if(choice == "S" || choice == "s") {
// get the salary
theWorker = getSalaried();
// pass in the dereferenced pointer to print out the info
printWorker(*theWorker);
}
return 0;
}
// method that gets the information -- creates a new worker object -- returns a pointer to the object
worker* getHourly() {
worker newWorker;
// set the isSalaried equal to false
newWorker.isSalaried = worker::NOTSALARIED; // equals 0 -- FALSE
cout << "Enter the number of hours worked: ";
// take in the hours worked
cin >> newWorker.info.h.numberHours;
cout << "Enter the hourly pay rate: ";
// take in the hourly rate
cin >> newWorker.info.h.hourlyRate;
return &newWorker;
}
worker* getSalaried() {
worker newWorker;
// set the kind equal to SALARIED
newWorker.isSalaried = worker::ISSALARIED; // equals 1 -- TRUE
cout << "Enter the salary amount: ";
// take in the salary
cin >> newWorker.info.s.salaryAmount;
cout << "Enter the bonus amount: ";
// take in the bonus
cin >> newWorker.info.s.bonusAmount;
return &newWorker;
}
void printWorker(worker theWorker) {
double grossPay;
// take care of the SALARIED first
if (theWorker.isSalaried) {
// add the salary to the bonus amount
grossPay = (theWorker.info.s.salaryAmount + theWorker.info.s.bonusAmount);
// print out the info
cout << "Salaried Worker" << endl;
// print out the salary
cout << "Salary: $" << theWorker.info.s.salaryAmount << endl;
// print out the bonus
cout << "Bonus: $" << theWorker.info.s.bonusAmount << endl;
}
// now, take care of the HOURLY
if ( !(theWorker.isSalaried) ) {
// get the product of the number of hours worked and the hourly rate
grossPay = (theWorker.info.h.numberHours * theWorker.info.h.hourlyRate);
// print out the info
cout << "Hourly Worker" << endl;
// print out the number of hours worked
cout << "\tHours: " << theWorker.info.h.numberHours << endl;
// print out the rate
cout << "\tRate: $" << theWorker.info.h.hourlyRate << endl;
}
// print out the last portion here, since this code will be executed for both
cout << "\t--------" << endl;
cout << "\tGross Pay: $" << grossPay << endl;
}
自从...
worker* getSalaried() {
worker newWorker;
...
return &newWorker;
}
你return一个局部变量的地址。因此 newWorker
的生命周期在 getSalaried
结束后结束,并且在其生命周期结束后访问对象是未定义的行为(例如提供 "chunk")。为了克服这个问题,你可以 return 一个 worker
-struct 本身(不是指向它的指针),或者你可以将 worker
的实例传递给函数,这样它就可以直接写进去。
我在代码块上尝试了上面的代码,它可以工作,但我确信这段代码每次都不安全 运行。
你的问题的原因是:你的 2 function
worker* getHourly()
{
worker newWorker;
...
return &newWorker;
}
worker* getSalaried() {
worker newWorker;
...
return &newWorker;
}
在这 2 个函数中,您从 worker 创建一个局部变量,然后您 return 将其地址编辑到 main 的调用者。
由于局部变量已从内存中删除,因此在函数终止后,main 中的指针 "theWorker" 在内存中保存了一个不再属于您的地址,这可能会导致您的问题。
你必须做出两种解决方案之一:
第一个,保持函数原样,但在函数中,定义一个指针而不是变量,并将其分配为动态分配如下:
worker* getHourly()
{
worker* newWorker;
newWorker = new (worker)
...
return newWorker;
}
worker* getSalaried() {
worker* newWorker;
newWorker = new (worker);
...
return &newWorker;
}
第二种:让2函数return一个变量代替地址如下:
worker getHourly()
{
worker newWorker;
...
return newWorker;
}
worker getSalaried() {
worker newWorker;
...
return &newWorker;
}
我正在为学校做一个项目,需要建立这种代码结构并使其正常工作。 问题: 我需要正确访问联合成员(h 和 s),而不是获取随机的内存数据块——实际上取回我存储的数字。我确实理解联合是如何工作的,所以我很困惑为什么我的代码给我随机数据而不是我存储在那里的数字。 注意:我确实在寻找这个问题的其他答案(因为这听起来像是一个很常见的语法问题),但其他解决方案并不真正适合我的情况。
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
struct worker {
enum kind {NOTSALARIED, ISSALRIED};
bool isSalaried;
union {
struct hourly{
double numberHours;
double hourlyRate;
} h; // end of 'hourly' struct
struct salaried{
double salaryAmount;
double bonusAmount;
} s; // end of 'salaried' struct
} info; // end of 'info' union
};
/// PROTOTYPE section
worker* getHourly();
worker* getSalaried();
void printWorker(worker);
int main() {
worker *theWorker; // avoids making another 'worker' object for no reason
// format code for 'double' values
cout << fixed << showpoint << setprecision(2);
// used string so avoid user entering name with the correct first character
string choice;
cout << "(H)ourly or (S)alary? ";
getline(cin, choice);
/// LOGIC SECTION: Checks what the user entered
if(choice == "H" || choice == "h") {
// get the salary
theWorker = getHourly();
// pass in the dereferenced pointer to print out the info
printWorker(*theWorker);
}
if(choice == "S" || choice == "s") {
// get the salary
theWorker = getSalaried();
// pass in the dereferenced pointer to print out the info
printWorker(*theWorker);
}
return 0;
}
// method that gets the information -- creates a new worker object -- returns a pointer to the object
worker* getHourly() {
worker newWorker;
// set the isSalaried equal to false
newWorker.isSalaried = worker::NOTSALARIED; // equals 0 -- FALSE
cout << "Enter the number of hours worked: ";
// take in the hours worked
cin >> newWorker.info.h.numberHours;
cout << "Enter the hourly pay rate: ";
// take in the hourly rate
cin >> newWorker.info.h.hourlyRate;
return &newWorker;
}
worker* getSalaried() {
worker newWorker;
// set the kind equal to SALARIED
newWorker.isSalaried = worker::ISSALARIED; // equals 1 -- TRUE
cout << "Enter the salary amount: ";
// take in the salary
cin >> newWorker.info.s.salaryAmount;
cout << "Enter the bonus amount: ";
// take in the bonus
cin >> newWorker.info.s.bonusAmount;
return &newWorker;
}
void printWorker(worker theWorker) {
double grossPay;
// take care of the SALARIED first
if (theWorker.isSalaried) {
// add the salary to the bonus amount
grossPay = (theWorker.info.s.salaryAmount + theWorker.info.s.bonusAmount);
// print out the info
cout << "Salaried Worker" << endl;
// print out the salary
cout << "Salary: $" << theWorker.info.s.salaryAmount << endl;
// print out the bonus
cout << "Bonus: $" << theWorker.info.s.bonusAmount << endl;
}
// now, take care of the HOURLY
if ( !(theWorker.isSalaried) ) {
// get the product of the number of hours worked and the hourly rate
grossPay = (theWorker.info.h.numberHours * theWorker.info.h.hourlyRate);
// print out the info
cout << "Hourly Worker" << endl;
// print out the number of hours worked
cout << "\tHours: " << theWorker.info.h.numberHours << endl;
// print out the rate
cout << "\tRate: $" << theWorker.info.h.hourlyRate << endl;
}
// print out the last portion here, since this code will be executed for both
cout << "\t--------" << endl;
cout << "\tGross Pay: $" << grossPay << endl;
}
自从...
worker* getSalaried() {
worker newWorker;
...
return &newWorker;
}
你return一个局部变量的地址。因此 newWorker
的生命周期在 getSalaried
结束后结束,并且在其生命周期结束后访问对象是未定义的行为(例如提供 "chunk")。为了克服这个问题,你可以 return 一个 worker
-struct 本身(不是指向它的指针),或者你可以将 worker
的实例传递给函数,这样它就可以直接写进去。
我在代码块上尝试了上面的代码,它可以工作,但我确信这段代码每次都不安全 运行。 你的问题的原因是:你的 2 function
worker* getHourly()
{
worker newWorker;
...
return &newWorker;
}
worker* getSalaried() {
worker newWorker;
...
return &newWorker;
}
在这 2 个函数中,您从 worker 创建一个局部变量,然后您 return 将其地址编辑到 main 的调用者。 由于局部变量已从内存中删除,因此在函数终止后,main 中的指针 "theWorker" 在内存中保存了一个不再属于您的地址,这可能会导致您的问题。 你必须做出两种解决方案之一: 第一个,保持函数原样,但在函数中,定义一个指针而不是变量,并将其分配为动态分配如下:
worker* getHourly()
{
worker* newWorker;
newWorker = new (worker)
...
return newWorker;
}
worker* getSalaried() {
worker* newWorker;
newWorker = new (worker);
...
return &newWorker;
}
第二种:让2函数return一个变量代替地址如下:
worker getHourly()
{
worker newWorker;
...
return newWorker;
}
worker getSalaried() {
worker newWorker;
...
return &newWorker;
}