动态分配班级 [英] Dynamic allocation of classes
问题描述
我对对象数组分配有疑问,
问题是这样的:
我有一个叫做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屋!