2015-06-25 4 views
2

, поэтому я новичок в C++ (с java в качестве фона), и я проходил через copy constructor и destructor раздел, но я до сих пор его не понимаю. Пример, который я покажу вам, взят из tutorialpoints.com. Поэтому у меня есть этот код, но результат меня просто смущает.C++! Как деструкторы называются

#include <iostream> 

using namespace std; 

class Line 
{ 
    public: 
     int getLength(void); 
     Line(int len);    // simple constructor 
     Line(const Line &obj); // copy constructor 
     ~Line();      // destructor 

    private: 
     int *ptr; 
}; 

// Member functions definitions including constructor 
Line::Line(int len) 
{ 
    cout << "Normal constructor allocating ptr" << endl; 
    // allocate memory for the pointer; 
    ptr = new int; 
    *ptr = len; 
} 

Line::Line(const Line &obj) 
{ 
    cout << "Copy constructor allocating ptr." << endl; 
    ptr = new int; 
    *ptr = *obj.ptr; // copy the value 
} 

Line::~Line(void) 
{ 
    cout << "Freeing memory!" << endl; 
    delete ptr; 
} 
int Line::getLength(void) 
{ 
    return *ptr; 
} 

void display(Line obj) 
{ 
    cout << "Length of line : " << obj.getLength() <<endl; 
} 

// Main function for the program 
int main() 
{ 
    Line line1(10); //Line 1*************************** 

    Line line2 = line1; // This also calls copy constructor 

    display(line1); 
    display(line2); 

    return 0; 
} 

Выход

Normal constructor allocating ptr 
Copy constructor allocating ptr. 
Copy constructor allocating ptr. 
Length of line : 10 
Freeing memory! 
Copy constructor allocating ptr. 
Length of line : 10 
Freeing memory! 
Freeing memory! 
Freeing memory! 

Таким образом, в строке 1 (Main), почему это также вызвать конструктор копирования, когда он имеет свой собственный аргумент?
Также после первого вызова метода display почему есть еще один звонок на номер copy constructor?
это вход я ожидал бы

`Normal constructor allocating ptr //Because Line one has its argument 
Copy constructor allocating ptr. //Because Line2 is a copy of Line1 
Length of line : 10 
Freeing memory! // Call to destructor after Line1 is desplayed 
// Memory leak Since Line2 is now pointing to nothing, i guess is what we call `shallow pointers?!` 

Извините, если это было слишком долго, надеюсь, я была ясна. PS Я только знаком с обычными указателями!

+4

Упростите свой тестовый код 'main' до тех пор, пока вы не сузите, какие строки принадлежат к какой инструкции. Вы делаете слишком много сразу. –

+0

Мне также нужно понять, почему это принадлежит! – Bobby

+0

Думаю, чтобы ответить на ваш вопрос в названии - деструктор вызывается, когда объект выходит за рамки. [См. Здесь пример] (https://ideone.com/pL8ag9). – erip

ответ

8

Что вас сбивает с толку: display занимает Line. Когда вы передаете функцию Line в функцию display, она копирует ее (вызывает копию ctor) в свой локальный аргумент и когда функция display заканчивается, этот локальный аргумент выходит за пределы области действия, а скопированный Line разрушает.

int main() 
{ 
    Line line1(10); // calls ctor that takes an int 

    Line line2 = line1; // calls copy ctor 

    display(line1); // calls copy ctor, prints, and then destructs the copy 
    display(line2); // calls copy ctor, prints, and then destructs the copy 

    return 0; 
} // line 2 goes out of scope and destructs, then line 1 does the same 
+0

Пятно на !!!! Большое спасибо, но одна вещь, которую я тоже не понимаю, состоит в том, что поскольку строки 'line2' и' line1' указывают на одно и то же место, как они дважды разрушаются? если вы знаете, что я имею в виду – Bobby

+0

@Bobby, они не указывают на то же место. 'line2' выделяет некоторую новую память и копирует содержимое из того, что указывает' line1.ptr' в свое собственное распределение. Это делается в копии ctor. Если он сделал то, что вы только что описали, он будет читать 'ptr = obj.ptr;' в копии ctor, а 'line1' и' line2' будут указывать на одно и то же. – David

+1

Хорошо. Спасибо, поэтому это была глубокая копия! – Bobby

0

Таким образом, в строке 1 (Main), почему это также вызвать конструктор копирования, когда это имеет свой собственный аргумент?

Это не вызовет конструктор копирования, прокомментируйте ваш код в основном и попробуйте. live_demo:http://coliru.stacked-crooked.com/a/64ad2d47a7ee953b

Также после первого вызова на дисплей метод, почему есть другой вызов конструктора копирования?

void display(Line obj) 

При вызове этой функции, так как ваш мимолетный аргумент по системе ценностей создает локальную копию объекта с именем obj функционировать, это происходит с помощью конструктора копирования вашего класса. Эта локальная область объектов будет завершена, как только выполнение завершит объем вашей функции display.

0

Здесь представлена ​​каждая часть основного, а также то, что она печатает.

Линия 1 (10); // Линия 1 ***************************

Normal constructor allocating ptr 

Линия line2 = строка1; // Это также вызывает конструктор копирования

Copy constructor allocating ptr. 

дисплей (строка1);

Copy constructor allocating ptr. 
Length of line : 10 
Freeing memory! 

дисплей (строка2);

Copy constructor allocating ptr. 
Length of line : 10 
Freeing memory! 

возвращение 0; }

Freeing memory! 
Freeing memory! 

Вы передаете в Line по значению, так он копирует Line у вас есть, вызывает функцию, а затем конец этой функции удаляет Line он получил.

1

Компилятор испускает код, который автоматически вызывает деструктор при явном уничтожении объекта (например, delete на объекте, созданном с помощью оператора new) или доходит до конца его срока службы (например, временный разрушенный, когда он больше не нужен, объявленный переменная, выходящая за рамки).

В своем коде (как вы его во время моего написания этого) последовательность событий

  • line1 построен
  • line2 построен как копия line1
  • line1 является передается по значению до display(). Это создает временную копию line1. Когда возвращается display(), деструктор вызывается для временного.
  • line2 передается по значению до display(). Это создает временную копию line2. Когда возвращается display(), деструктор вызывается для временного.
  • main() возвращается.
  • line1 и line2 разрушены в обратном порядке их конструкции и деструктор, вызываемый для каждого.
+0

Большое вам спасибо! это действительно помогло мне понять. Не знал о «временной» копии! – Bobby

Смежные вопросы