动态分配班级 [英] Dynamic allocation of classes

查看:91
本文介绍了动态分配班级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对对象数组分配有疑问,
问题是这样的:
我有一个叫做person的类:

I have a question about object array allocation, the problem is this: I have a class called person :

class Person {
    char* name;
    int ID;


public:
    Person(char* name = NULL, int ID = 0) :name(name), ID(ID) {};
}

,我正在尝试让一群人像这样:

and I'm trying to make an array of persons like so:

Person *pArr = new Person[size];

之后,我从文件中提取数据(char *为字符串,int为ID)
和我使用for循环,并使用构造函数将人员放置在循环内,如下所示:

and after that I extract the data from a file (char* for string and int for ID) and I use for loop and the constructors to place the persons inside the loop like so:

for (int j = 0; j < size3; j++) {
pArr[j] = Person(Name, id);
}

完成程序后,我想使用析构函数并释放分配的字符串它存储在char *名称中,但是当我添加Destructor时,它在循环结束后立即被触发,每个创建的Person被立即破坏

我知道可以创建一个指针数组并同时分配了该人,但在此分配中,我想这样做,
是否有正确的方法来执行,而不会立即触发析构函数?

after I finish my program I want to use the Destructor and free the allocated string that's stored inside the char* name, but when I add the Destructor it gets triggered right after the loops ends, every Person that's being created is destroyed immediately, I know its possible to make an array of pointers and allocated the person aswell, but in this assignment I'm suppose to do it like this, is there a right way to do it without triggering the destructor right away?

推荐答案

在这一行:

pArr[j] = Person(Name, id);

您正在创建临时 对象,然后将其分配给 pArr [j] 对象。 Person 没有定义显式的副本分配运算符,因此编译器会自动为您生成一个副本,它只需将值从一个对象逐个成员复制到另一个对象即可。

You are creating a temporary Person object, and then assigning it to the pArr[j] object. Person has no explicit copy assignment operator defined, so the compiler auto-generates one for you, which simply performs a member-by-member copy of values from one object to another.

当临时文件超出; 的范围时,它将被自动销毁。编译器生成的赋值运算符将 name 指针原样复制到 pArr [j] 对象,因此,如果 Person 有一个析构函数,可释放其名称 pArr [j] 对象将带有悬空的名称指针,以指向释放的内存。

When the temporary goes out of scope on the ;, it is automatically destroyed. The compiler-generated assignment operator copied the name pointer as-is to the pArr[j] object, so if Person has a destructor that frees its name, the pArr[j] object will be left with a dangling name pointer to freed memory.

您的 Person 类未遵循三人规则


三个规则(也称为三大律或三大律)是一条经验法则在C ++(C ++ 11之前的版本)中声称,如果一个类定义了以下一个(或多个),则它可能应该明确定义所有三个:

The rule of three (also known as the Law of The Big Three or The Big Three) is a rule of thumb in C++ (prior to C++11) that claims that if a class defines one (or more) of the following it should probably explicitly define all three:


  • 析构函数

  • 副本构造函数

  • 副本分配运算符

因为您想要 Person 有一个析构函数, ees name ,它还需要一个拷贝构造函数和一个拷贝赋值运算符,以便可以为析构函数制作 name 的副本免费,例如:

Since you want Person to have a destructor that frees name, it also needs a copy constructor and a copy assignment operator so it can make copies of name for the destructor to free, eg:

class Person
{
    char* name;
    int id;

public:
    Person(const char* Name = NULL, int ID = 0)
        : name(new char[std::strlen(Name)+1]), id(ID)
    {
        std::strcpy(name, Name);
    }

    Person(const Person &src)
        : name(new char[std::strlen(src.name)+1]), id(src.id)
    {
        std::strcpy(name, src.name);
    }

    ~Person()
    {
        delete[] name;
    }

    Person& operator=(const Person &rhs)
    {
        if (&rhs != this)
        {
            Person tmp(rhs);

            //std::swap(tmp.name, name);
            char *p = tmp.name;
            tmp.name = name;
            name = p;

            id = tmp.id;
        }
        return *this;
    }
};

现在,回到此行:

pArr[j] = Person(Name, id);

临时文件将被复制到 pArr [j] 安全正确。只是请注意,如果您事先动态分配了 Name ,则现在必须事后释放它,因为 Person 拥有自己的名称内部副本。

The temporary will be copied to pArr[j] safely and properly. Just note that if you dynamically allocated Name beforehand, you will now have to free it afterwards, since Person makes its own internal copy.

如果可以将 char * 更改为 std :: string ,那么您不必担心编译器会生成默认副本,因为 std :: string 符合三则规则,并将被正确复制:

If you can change char* to std::string, then you don't have to worry about the compiler making default copies, since std::string is compliant with the Rule of Three and will be copied properly:

class Person
{
    std::string name;
    int id;

public:
    Person(const std::string &name = std::string(), int ID = 0)
        : name(name), id(ID)
    {
    }

    // no explicit copy constructor, destructor, or
    // assignment operator is needed, as compiler-generated
    // defaults will suffice...
};

这篇关于动态分配班级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆