Конструкторы, берущие ссылки в C ++ - PullRequest
1 голос
/ 18 мая 2010

Я пытаюсь создать конструктор, используя ссылку на объект. После создания объекта по ссылке мне нужно распечатать значения полей обоих объектов. Затем я должен удалить первый объект, и еще раз показать значения полей обоих объектов. Мой класс Person выглядит так:

class Person {   
    char* name;
    int age;
public:

    Person(){
        int size=0;
        cout << "Give length of char*" << endl;
        cin >> size;
        name = new char[size];      
        age = 0;
    }

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

void init(char* n, int a) {
    name = n;
    age = a;
} 
}; 

Вот моя реализация (с использованием функции show ()). Мой профессор сказал, что если это задание написано правильно, оно вернет ошибку.

#include <iostream>
using namespace std;

class Person {   
    char* name;
    int age;
public:

    Person(){
        int size=0;
        cout << "Give length of char*" << endl;
        cin >> size;
        name = new char[size];      
        age = 0;
    }

    Person(const Person& p){
        name = p.name;
        age = p.age;
    }

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

void init(char* n, int a) {
    name = n;
    age = a;
}


void show(char* n, int a){
    cout << "Name: " << name << "," << "age: " << age << "," << endl; 
}

}; 


int main(void) {
    Person *p = new Person;  
    p->init("Mary", 25);

    p->show();

    Person &p = pRef;
    pRef->name = "Tom";
    pRef->age = 18;

    Person *p2 = new Person(pRef);

    p->show();
    p2->show();

    system("PAUSE");
    return 0;
}

Ответы [ 2 ]

1 голос
/ 18 мая 2010

Проблема с вашим конструктором копирования заключается в том, что он просто назначает p.name:

name = p.name // Now this and p hold a pointer to the same memory

Поскольку и this, и p теперь содержат указатель на одно и то же место в памяти, то, что будет уничтожено первым, освободит память, в то время как второе будет содержать указатель на несуществующий объект. Впоследствии использование этого указателя или его удаление приведет к неопределенному поведению. Решение состоит в том, чтобы выделить новый массив для имени и скопировать содержимое p.name в этот массив, чтобы память не была общей.

Аналогично, ваша функция инициализации перезаписывает имя, игнорируя тот факт, что память была выделена (это утечка памяти), а также игнорируя тот факт, что строка будет позже уничтожена (даже если вызывающая сторона, вероятно, ожидает владения и освобождения этой строки). сама строка). Также я должен отметить, что ваша функция show принимает параметр «n», но вместо этого использует «name». Ваша функция show, вероятно, не должна принимать какие-либо параметры (в действительности, то, как вы ее называете, подразумевает, что она этого не делает), учитывая, что все необходимые поля уже присутствуют в вашем классе (или, возможно, вы намеревались сделать это автономной функцией). что занимает поля класса?). Вы должны еще раз взглянуть на свой код для дополнительных ошибок.

0 голосов
/ 18 мая 2010

Прежде всего, попробуйте скомпилировать свой код (обычно хорошей идеей является компиляция кода перед публикацией его на SO.) Он содержит несколько ошибок, и компилятор покажет их. Во второй части будет изменено следующее:

p->init("Mary", 25);

до

{
  std::string mary("Mary");
  p->init(mary.c_str(), 25);
}

Он должен выдавать ошибку во время выполнения и даст вам шанс найти проблему в вашей реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...