You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++抽象类对象创建及员工管理类实现问题求助

Hey there! Let's tackle your two questions one by one, and fix that frustrating "cannot create abstract class object" error you're running into with your code.


1. Can we create objects of abstract classes in C++?

Short answer: No, you can't directly create an object of an abstract class. This is intentional—abstract classes are designed to define a common interface that derived classes must implement, not to be instantiated on their own. The presence of at least one pure virtual function (like your virtual void print()=0;) marks the class as abstract.

Instead, you work with pointers or references to the abstract class type. These pointers/references can point to objects of concrete derived classes (classes that implement all pure virtual functions from the abstract base). This is how polymorphism works in C++—it lets you treat all employee types the same way while still calling their specific behaviors.


2. Fixing your error & implementing the Company class

Let's break down why you're getting that error first, then walk through a corrected version of your code:

Why your current code fails:

  • Your PermanentEmployee and ContractualEmployee classes don't implement the pure virtual print() function from Employee. That makes them abstract classes too—so you can't create objects of them either!
  • You tried to declare PermanentEmployee PE; without a default constructor (your PermanentEmployee only has a parameterized constructor).
  • PermanentEmployee uses protected inheritance, which breaks the "is-a" relationship with Employee—you won't be able to use it where an Employee* is expected, which defeats the purpose of polymorphism for your company's employee list.
  • Your Employee constructor is declared but not implemented, which would cause a linker error later.
  • The Company class's list is a raw pointer, which isn't flexible enough to store an arbitrary number of employees.

Corrected Code

#include<iostream>
#include<string>
#include<vector> // For dynamic, resizable employee storage
using namespace std;

struct dob { int date, month, year; }; // Fixed typo: "day" -> "month" (likely a mistake)

class Employee {
public:
    string Name;
    int ID;
    string Department;
    double MonthlyGrossSalary;
    double MonthlyNetSalary;

    // Implement the base class constructor
    Employee(string name, int id, string dep, double mgs, double mns)
        : Name(name), ID(id), Department(dep), MonthlyGrossSalary(mgs), MonthlyNetSalary(mns) {}

    // Empty implementations for now (you can expand these later)
    virtual void CalculateAnnualIncomeTax() {}
    virtual void CalculateMonthlyIncomeTax() {}
    virtual void print() = 0; // Pure virtual function - MUST be implemented by derived classes
};

// Use public inheritance to maintain "is-a Employee" relationship
class PermanentEmployee : public Employee {
public:
    double ProvidentFund;
    double AnnualMedicalInsuranceLimit;

    PermanentEmployee(double pf, double amil, string name, int id, string dep, double mgs, double mns)
        : Employee(name, id, dep, mgs, mns), ProvidentFund(pf), AnnualMedicalInsuranceLimit(amil) {}

    // Implement the pure virtual print function
    void print() override {
        cout << "Permanent Employee Details:\n";
        cout << "Name: " << Name << "\nID: " << ID << "\nDepartment: " << Department << "\n";
        cout << "Gross Salary: " << MonthlyGrossSalary << "\nNet Salary: " << MonthlyNetSalary << "\n";
        cout << "Provident Fund: " << ProvidentFund << "\nMedical Limit: " << AnnualMedicalInsuranceLimit << "\n";
    }
};

class ContractualEmployee : public Employee {
public:
    dob ContractStartDate;
    dob ContractEndDate;

    ContractualEmployee(dob csd, dob ced, string name, int id, string dep, double mgs, double mns)
        : Employee(name, id, dep, mgs, mns), ContractStartDate(csd), ContractEndDate(ced) {}

    // Implement the pure virtual print function
    void print() override {
        cout << "Contractual Employee Details:\n";
        cout << "Name: " << Name << "\nID: " << ID << "\nDepartment: " << Department << "\n";
        cout << "Gross Salary: " << MonthlyGrossSalary << "\nNet Salary: " << MonthlyNetSalary << "\n";
        cout << "Contract Start: " << ContractStartDate.date << "/" << ContractStartDate.month << "/" << ContractStartDate.year << "\n";
        cout << "Contract End: " << ContractEndDate.date << "/" << ContractEndDate.month << "/" << ContractEndDate.year << "\n";
    }
};

class Company {
private:
    vector<Employee*> employees; // Dynamic list to store any number of employees
public:
    // Add a new employee to the company
    void AddEmployee(Employee* emp) {
        employees.push_back(emp);
    }

    // Print details of all employees in the company
    void PrintAllEmployees() {
        for (auto emp : employees) {
            emp->print();
            cout << "-------------------------\n";
        }
    }

    // Clean up dynamically allocated memory to avoid leaks
    ~Company() {
        for (auto emp : employees) {
            delete emp;
        }
    }
};

void datainput(string&, int&, string&, double&, double&);
void getContractDates(dob&, dob&);

int main() {
    char option;
    string name;
    string dep;
    int id;
    double mgs;
    double mns;
    Company myCompany;

    do {
        cout << "\nSelect Type of Employee\n";
        cout << "Permanent Employee [P][p]\n";
        cout << "Contractual Employee [C][c]\n";
        cout << "Quit & Print All [Q][q]\n";
        cout << "Enter your choice: ";
        cin >> option;

        switch(option) {
            case 'P':
            case 'p': {
                datainput(name, id, dep, mgs, mns);
                double pf, amil;
                cout << "Enter Provident Fund: ";
                cin >> pf;
                cout << "Enter Annual Medical Insurance Limit: ";
                cin >> amil;
                // Create employee dynamically and add to company
                myCompany.AddEmployee(new PermanentEmployee(pf, amil, name, id, dep, mgs, mns));
                cout << "Permanent employee added!\n";
                break;
            }
            case 'C':
            case 'c': {
                datainput(name, id, dep, mgs, mns);
                dob start, end;
                getContractDates(start, end);
                // Create employee dynamically and add to company
                myCompany.AddEmployee(new ContractualEmployee(start, end, name, id, dep, mgs, mns));
                cout << "Contractual employee added!\n";
                break;
            }
            case 'Q':
            case 'q':
                cout << "\n--- All Company Employees ---\n";
                myCompany.PrintAllEmployees();
                break;
            default:
                cout << "Invalid option! Try again.\n";
        }
    } while (option != 'Q' && option != 'q');

    return 0;
}

void datainput(string& n, int& no, string& d, double& mg, double& mn) {
    cout << "\nEnter Employee Data\n";
    cout << "Name: ";
    cin >> n;
    cout << "ID: ";
    cin >> no;
    cout << "Department: ";
    cin >> d;
    cout << "Monthly Gross Salary: ";
    cin >> mg;
    cout << "Monthly Net Salary: ";
    cin >> mn;
}

void getContractDates(dob& start, dob& end) {
    cout << "\nEnter Contract Start Date (date month year): ";
    cin >> start.date >> start.month >> start.year;
    cout << "Enter Contract End Date (date month year): ";
    cin >> end.date >> end.month >> end.year;
}

Key changes made:

  1. Implemented pure virtual print(): Both derived classes now have their own print() implementation, making them concrete (non-abstract) classes that can be instantiated.
  2. Public inheritance: PermanentEmployee now uses public inheritance, so it's properly recognized as an Employee type for polymorphism.
  3. Dynamic storage with std::vector: The Company class uses vector<Employee*> to store any number of employees, which is flexible and safe.
  4. Dynamic object creation: Employees are created with new (and cleaned up in the Company destructor) so they can be stored as Employee* pointers.
  5. Added loop for multiple employees: The main function lets you add as many employees as you want until you quit, then prints all of them.

内容的提问来源于stack exchange,提问作者Rimsha Nasir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:22:09