skippr
skippr

Reputation: 2706

Strings, Unions, and Pointers

Note: This is an assignment. I'm looking for solutions using unions, because it's part of the assignment. I provide the solution I want to use, but I need help putting this concept and approach into perspective. ---

I'm aware of how strings don't work in unions, and this question has been asked before - but they all seem to end suggesting Boost. I saw someone, however, suggest pointers but it appeared overlooked and I wanted more clarification on it. Below I have two structs, with a union containing pointers to both structs as a workaround:

struct HourlyInfo {
    string firstName;
    string lastName;
    string title;
    int hoursWorked;
    double hourlyRate;
};

struct SalaryInfo {
    string firstName;
    string lastName;
    string title;
    double salary;
    double bonus;
};

union Employee {
    HourlyInfo *hourlyEmployee;
    SalaryInfo *salaryEmployee;
};

Is there anything wrong with this method? To me it seems to defeat the purpose of a union.

EDIT: This is an assignment, but it's very open-ended. I'm not looking for answers, just explanations and input on why a certain method might or should be avoided. My alternative is using cstring, but I'm trying to weigh the pointer method (in order to have the convenience of string) against just using cstring.

EDIT #2: I understand that unions will make one struct void once the other is defined. I will be creating an array of these unions, and the use of union for this case is warranted because any employee is EITHER hourly or salary. My concern is the use of strings and pointers as a workaround.

Upvotes: 3

Views: 421

Answers (4)

Oleg Pyzhcov
Oleg Pyzhcov

Reputation: 7353

You could also possibly use anonymous unions and structs:

struct Employee {
    string firstName;
    string lastName;
    string title;
    bool isHourly;
    union {
        struct {
            double hourlyRate;
            int hoursWorked;
        } hourly;
        struct {
            double salary;
            double bonus;
        } salaried;
    };
};

Then access them via Employee emp; emp.hourly.hourlyRate = 100; You may even remove struct names - then you shall be able to access their fields as emp.salary. Your approach is fine still - assuming you have where to store info to check if the worker is salaried or hourly. The other pointer won't be null, it will be the same pointer to the same data - but treated like another type, so it may lead to undefined behavior.

I myself would still prefer something like strategy pattern though.

Upvotes: 1

Seva Alekseyev
Seva Alekseyev

Reputation: 61388

The C++ way of doing this is with inheritance.

struct EmployeeInfo {
    string firstName;
    string lastName;
    string title;
};

struct HourlyInfo : public EmployeeInfo {
    int hoursWorked;
    double hourlyRate;
};

struct SalaryInfo : public EmployeeInfo {
    double salary;
    double bonus;
};

Give it a virtual destructor so that you can delete by base class pointer. And store a pointer to EmployeeInfo instead of the union. Upcast as necessary. And account for the difference via virtual functions, or an "Employee type" variable somewhere. In the union scenario, you'll need it anyway, as the union itself doesn't tell you which data item in it is the relevant one.

Yes, you can derive struct's. And you can have member functions in them, too.

Upvotes: 2

Manav Kataria
Manav Kataria

Reputation: 5320

I don't see any issue here.

Note that:

  • You won't be able to use both pointers to store different values simultaneously.
  • You aren't saving much by encapsulating two (struct) pointers in a union.

Upvotes: 0

Bozemoto
Bozemoto

Reputation: 226

Sorry didn't see they were pointers, yes that is completely pointless. Also you'll get a crash when allocating a HourlyInfo and accessing the SalaryInfo::bonus member. Since one struct is (possibly) larger than the other. (if int = 32 bit and double = 64bit)

Upvotes: 0

Related Questions