C ++对象的构造函数

时间:2010-05-18 09:56:58

标签: c++ dynamic-memory-allocation

我的课程人员如下:

class Person {   
    char* name;
    int age;
};

现在我需要添加两个结构。一个不带参数的,将字段值插入动态分配的资源。第二个由初始化列表初始化的(char *,int)参数。最后一部分是定义一个析构函数,显示有关销毁对象和解除分配动态分配资源的信息。如何执行此任务?

这就是我已经拥有的东西:

class Person {   
    char* name;
    int age;
public:
    Person(){
        this->name = new *char;
        this->age = new int;
    }

    Person(char* c, int i){
    }
};

5 个答案:

答案 0 :(得分:3)

在默认构造函数中,char数组的分配应包括其所需的大小,例如

this->name = new char[32];

请注意,此大小包含终止0字符,因此您可以在此数组中存储的名称的有效长度为31。

在参数化构造函数中,您只需将给定参数分配给类成员即可。

在析构函数中,您需要释放动态分配的资源 - 确保在仅释放分配了delete[]的内存时使用new[]

~Person(){
    std::cout << "Destroying resources" << std::endl;
    delete[] name;
    delete age;
}

更新:我错过了这个:如果您想动态分配age,则应将其声明为int* age

我认为这个练习的目的是练习动态分配/解除分配;在这种情况下,它很好。但是,一般情况下,动态分配int并不是好的做法,而应该使用char*来代替std::string,它会自动安全地为您处理内存分配。 / p>

答案 1 :(得分:2)

通过使用C ++ string类,您可以忘记手动(和危险)内存管理:

class Person {
    public:
        Person () : name_(""), age_(0) { }
        Person (const std::string& name, int age) : name_(name), age_(age) { }
    // There is no need for the destructor as the memory is managed by the string class.
};

另外see this link因为你应该总是使用初始化列表而不是构造函数中的赋值。

答案 2 :(得分:1)

鉴于您的声明,无法初始化age以动态分配内存,因为age不是指针。

您当然可以将age的类型更改为int*。但我不会这样做,它没有任何意义。目前尚不清楚作业是否真的要求动态分配(如果是的话 - 为什么?)。

对于name,另一方面,您可以按@Péter所述进行操作。但是在大多数情况下,这不是一个非常好的解决方案,因为C ++提供了string类,它将字符串操作很好地包装到类中。如果赋值允许,请使用string代替char*和动态内存分配。

答案 3 :(得分:0)

当您想要设置名称时,您也可以只分配复制名称所需的内存。 另外,当对象被破坏时,不要忘记释放分配的缓冲区!

class Person {   
    char* name;
    int age;
public:
    Person(){
        this->name = NULL;
        this->age = 0; // no need to allocate memory for basic types
    }

    ~Person(){
        delete [] name;
    }

    set(char* c, int i){
        this->age = i;

        // copy name if input pointer name is valid
        if (c != NULL){
            // if memory have already been allocated : delete first
            if (this->name != NULL){
                delete [] name;
                name = NULL;
            }
            // allocate memory : 1 more char for the trailing '\0'
            this->name = new char[strlen(c)+1];
            // copy string
            strcpy(this->name,c);
        }
    }
};

编辑并回答备注:

  • 简化析构函数,遵循Konrad Rudolf的建议
  • 我倾向于总是将未分配和解除分配的指针设置为NULL,以避免在未正确使用指针时选择随机内存位置,并且未分配的指针也更容易在debbuger中发现。
  • 我没注意第二种方法是构造函数,我认为它是一个setter ......改变了它。

答案 4 :(得分:0)

我建议使用字符串类而不是char *。

这样的事情:

class Person
{
 public:
  Person() : name(""), age(0) {}
  Person(const string& n, int a) : name(n), age(a) {}

  // whatever here.

  ~Person() {} // do nothing

 private:
  string name;
  int age;
};