在班级中使用动态分配的C风格字符串,并带有复制和分配操作员,给出了意外的结果

Using dynamically allocated c-style strings in a class with copy and assignment operator giving unexpected results

本文关键字:分配 复制 操作员 结果 意外 动态分配 字符串 风格      更新时间:2023-10-16

此程序汇编成功,但行不通。我想这与分配运营商或复制构造函数有关,但我不知道什么...

标题:

class employee{
    char *name;
    unsigned int salary;
public:
    employee();
    employee(const char*);
    employee(const char*,unsigned int);
    employee (const employee&);
    employee operator = (employee);
    void init(const char*,unsigned int);
    void print();
    ~employee();
};

cpp:

#include <iostream>
#include <string>
#include "class.h"
using namespace std;
employee::employee() : salary(1000)
{
    name=new char[20];
}
employee::employee(const char* ename) : salary(1000)
{
    strcpy_s(name,20,ename);
}
employee::employee(const char* ename,unsigned int salary)
{
    name=new char[20];
    strcpy_s(name,20,ename);
    this->salary=salary;
}
employee::employee(const employee& emp)
{
    name=new char[20];
    int i=0;
    while (name[i]!='') 
    {
        name[i]=emp.name[i];
        i++;
    }
    salary=emp.salary;
}
void employee::init(const char* ename, unsigned int salary)
{
    name=new char[20];
    strcpy_s(name,20,ename);
    this->salary=salary;
}
void employee::print()
{
    cout<<"name: ";
    int i=0;
    while (name[i]!='')
    {
        cout<<name[i];
        i++;
    }
    cout<<"n"<<"salary: "<<salary<<endl;
}
employee employee::operator = (employee emp)
{
    strcpy_s(name,20,const_cast <const char*>(emp.name));
    emp.salary=salary;
    return *this;
}
employee::~employee()
{
    delete [] name;
}

主:

#include <iostream>
#include "class.h"
using namespace std;

int main()
{
    employee emp1 ("Bill Jones",5000),emp5("Michael Adams");
    employee emp2;
    emp2=emp1;
    employee emp3;
    emp3=emp2;
    employee * workers= new employee [3];
    workers[0]=emp3;
    workers[1]= employee("katy Ashton");
    delete [] workers;
}

虽然您可能会作为练习进行此操作,但建议您阅读三个规则是什么?IT和类似的常见问题解答将指导您如何正确地超载复制/分配操作员并编写自己的复制构造函数并适当处理动态内存。现在,为了避免使用易于错误的代码,我建议您完全使用std::string并完全放弃过载。您的新课应该看起来像这样:

#include <iostream>
using namespace std;
class employee{
    std::string name;
    unsigned int salary;
public:
    employee();
    employee(std::string);
    employee(std::string,unsigned int);
    void init(std::string,unsigned int);
    void print();
    ~employee();
};
employee::employee() : salary(1000)
{
    name = "";
}
employee::employee(std::string ename) : salary(1000)
{
    name = ename;
}
employee::employee(std::string ename,unsigned int salary)
{
    name = ename;
    this->salary=salary;
}
void employee::print()
{
    cout<<"name: "<<name;
    cout<<"n"<<"salary: "<<salary<<endl;
}
employee::~employee()
{
}

int main()
{
    employee emp1 ("Bill Jones",5000),emp5("Michael Adams");
    employee emp2;
    emp2=emp1;
    employee emp3;
    emp3=emp2;
    employee * workers= new employee [3];
    workers[0]=emp3;
    workers[1]= employee("katy Ashton");
    for (int i = 0; i < 2; i++)
    {
        workers[i].print();
    }
    delete [] workers;
}

我认为您在员工构造函数中缺少name = new char[20];,该构建器仅获取名称参数

我不知道错误消息是什么,但我想原因是:

employee::employee(const char* ename) : salary(1000)
{
    strcpy_s(name,20,ename);
}

您不为name分配任何空间,然后稍后使用此构造函数:,emp5("Michael Adams");

因此,它崩溃(我猜)

我相信这部分是错误的:

while (name[i]!='') 
    {
        name[i]=emp.name[i];
        i++;
    }

while条件应为 emp.name[i]!=''。(考虑使用同样的事情的strcpy_s。)

另一个问题是您的employee::employee(const char* ename)构造函数,您将复制到数组中,而不是分配。您需要首先分配它:

employee::employee(const char* ename) : salary(1000)
{
    name = new char[20]; // typo! it was 10... better use defines in this situation!
    strcpy_s(name,20,ename);
}

当然,您应该更精确地描述您的问题。