tek4

Hàm tạo và hàm hủy C++

by - September. 26, 2021
Kiến thức
Học
<p>H&agrave;m tạo v&agrave; h&agrave;m hủy trong C++ l&agrave; hai kh&aacute;i niệm cơ bản trong qu&aacute; tr&igrave;nh lập tr&igrave;nh v&agrave; l&agrave;m việc với c&aacute;c đối tượng của một lớp. Trong b&agrave;i viết n&agrave;y, ch&uacute;ng ta sẽ t&igrave;m hiểu về h&agrave;m tạo v&agrave; h&agrave;m hủy trong C++ c&ugrave;ng với c&aacute;c v&iacute; dụ dẫn chứng.</p> <h2>H&agrave;m tạo</h2> <p>H&agrave;m tạo l&agrave; một kiểu h&agrave;m th&agrave;nh vi&ecirc;n đặc biệt được gọi tự động khi một đối tượng được tạo. Trong C ++, một h&agrave;m tạo c&oacute; c&ugrave;ng t&ecirc;n với t&ecirc;n của lớp v&agrave; n&oacute; kh&ocirc;ng c&oacute; kiểu trả về.</p> <p>V&iacute; dụ:</p> <pre class="language-cpp"><code>class sinh_vien { public: sinh_vien() { // Đoạn m&atilde; } };</code></pre> <p>Ở đ&acirc;y, h&agrave;m sinh_vien () l&agrave; một phương thức khởi tạo của lớp sinh_vien. Lưu &yacute; rằng h&agrave;m tạo c&oacute; c&ugrave;ng t&ecirc;n với lớp, kh&ocirc;ng c&oacute; kiểu trả về v&agrave; l&agrave; phương thức c&ocirc;ng khai, c&oacute; thể gọi bất cứ đ&acirc;u trong chương tr&igrave;nh.</p> <h2>H&agrave;m tạo mặc định trong C++</h2> <p>Một h&agrave;m khởi tạo kh&ocirc;ng c&oacute; tham số được gọi l&agrave; một h&agrave;m tạo mặc định. Trong v&iacute; dụ tr&ecirc;n, sinh_vien () l&agrave; một h&agrave;m tạo mặc định.</p> <p>V&iacute; dụ: H&agrave;m khởi tạo trong C++</p> <pre class="language-cpp"><code>#include &lt;iostream&gt; using namespace std; class sinh_vien { private: int ID_sv; public: sinh_vien() { ID_sv = 1; cout &lt;&lt; "ID sinh vien la: " &lt;&lt; ID_sv &lt;&lt; endl; } }; int main() { sinh_vien sv; return 0; }</code></pre> <p>Ở đ&acirc;y, khi đối tượng sv được tạo, h&agrave;m tạo sinh_vien () sẽ được gọi v&agrave; h&agrave;m n&agrave;y sẽ đặt biến ID_sv của đối tượng l&agrave; 1.</p> <p><strong>Ch&uacute; &yacute;: Nếu ch&uacute;ng ta chưa x&aacute;c định h&agrave;m tạo trong lớp, th&igrave; tr&igrave;nh bi&ecirc;n dịch C ++ sẽ tự động sinh ra một h&agrave;m tạo mặc định với đoạn m&atilde; trống v&agrave; kh&ocirc;ng c&oacute; tham số.</strong></p> <h2>H&agrave;m tạo c&oacute; tham số</h2> <p>Trong C ++, một h&agrave;m tạo với c&aacute;c tham số được gọi l&agrave; một phương thức khởi tạo chứa tham số. Đ&acirc;y l&agrave; phương ph&aacute;p thường d&ugrave;ng để khởi tạo c&aacute;c dữ liệu th&agrave;nh vi&ecirc;n.</p> <p>V&iacute; dụ: H&agrave;m tạo c&oacute; tham số</p> <pre class="language-cpp"><code>#include &lt;iostream&gt; using namespace std; class sinh_vien { private: int ID_sv; public: sinh_vien(int a) { ID_sv = a; } void in_thong_tin(){ cout &lt;&lt; "ID sinh vien la: " &lt;&lt; ID_sv &lt;&lt; endl; } }; int main() { sinh_vien sv(1); sv.in_thong_tin(); return 0; }</code></pre> <p>Kết quả:</p> <pre class="language-markup"><code>1</code></pre> <p>Ở đ&acirc;y, ch&uacute;ng ta đ&atilde; tạo một h&agrave;m khởi tạo chứa tham số sinh_vien () c&oacute; 1 tham số l&agrave; int a. Gi&aacute; trị trong tham số n&agrave;y được sử dụng để khởi tạo một gi&aacute; trị ID cho biến th&agrave;nh vi&ecirc;n l&agrave; ID_sv. Khi ch&uacute;ng ta tạo một đối tượng của lớp sinh_vien, ch&uacute;ng ta sẽ truyền gi&aacute; trị cho h&agrave;m tạo.</p> <p>V&iacute; dụ: sinh_vien sv(1);</p> <p>Với h&agrave;m khởi tạo g&aacute;n gi&aacute; trị cho biến th&agrave;nh vi&ecirc;n ID_sv, ta c&oacute; thể in ra được gi&aacute; trị m&agrave; đ&atilde; g&aacute;n.</p> <h2>H&agrave;m tạo sao ch&eacute;p</h2> <p>L&agrave; h&agrave;m được sử dụng để sao ch&eacute;p từ một đối tượng n&agrave;y sang đối tượng kh&aacute;c</p> <p>V&iacute; dụ:</p> <pre class="language-cpp"><code>#include &lt;iostream&gt; using namespace std; class sinh_vien { private: int ID_sv; public: sinh_vien(int a) { ID_sv = a; } sinh_vien(sinh_vien &amp;a){ ID_sv = a.ID_sv; } void in_thong_tin(){ cout &lt;&lt; "ID sinh vien la: " &lt;&lt; ID_sv &lt;&lt; endl; } }; int main() { sinh_vien sv(1); sv.in_thong_tin(); sinh_vien sv2 = sv; sv2.in_thong_tin(); return 0; }</code></pre> <p>Trong đoạn m&atilde; tr&ecirc;n, ta đ&atilde; thực hiện sao ch&eacute;p từ đối tượng sv sang đối tượng sv2 với c&aacute;c dữ liệu th&agrave;nh vi&ecirc;n. Đoạn m&atilde; của h&agrave;m tạo sao ch&eacute;p như sau:</p> <pre class="language-cpp"><code>sinh_vien(sinh_vien &amp;a){ ID_sv = a.ID_sv; }</code></pre> <p>Ch&uacute; &yacute; rằng tham số của h&agrave;m tạo n&agrave;y l&agrave; địa chỉ của một đối tượng của lớp sinh_vien. Sau đ&oacute;, ch&uacute;ng ta g&aacute;n gi&aacute; trị của c&aacute;c biến của đối tượng đầu ti&ecirc;n cho c&aacute;c biến tương ứng của đối tượng thứ hai. Trong h&agrave;m main (),ch&uacute;ng ta tạo hai đối tượng sv v&agrave; sv2 rồi sao ch&eacute;p nội dung của đối tượng đầu ti&ecirc;n sang đối tượng thứ hai: Sinh_vien sv2 = sv;</p> <p><strong>Ch&uacute; &yacute;: Một h&agrave;m tạo chủ yếu được sử dụng để khởi tạo c&aacute;c đối tượng. Ch&uacute;ng cũng được sử dụng để&nbsp; chạy c&aacute;c đoạn m&atilde; mặc định khi một đối tượng được tạo.</strong></p> <h1>H&agrave;m hủy</h1> <p><img class="aligncenter wp-image-7270 size-full" style="display: block; margin-left: auto; margin-right: auto;" src="https://tek4.vn/wp-content/uploads/2020/12/Capture-173.png" alt="H&agrave;m tạo v&agrave; h&agrave;m hủy C++" width="564" height="346" /></p> <p>H&agrave;m hủy l&agrave; một h&agrave;m th&agrave;nh vi&ecirc;n đặc biệt của một lớp v&agrave; hoạt động ho&agrave;n to&agrave;n đối lập với h&agrave;m tạo, kh&ocirc;ng giống như h&agrave;m tạo được sử dụng để khởi tạo một đối tượng, h&agrave;m hủy sẽ hủy (hoặc x&oacute;a) một đối tượng. H&agrave;m hủy sẽ được thực thi bất cứ khi n&agrave;o đối tượng của một lớp được thực hiện xong hoặc biểu thức delete được gọi v&agrave; &aacute;p dụng cho con trỏ trỏ tới đối tượng của lớp đ&oacute;. H&agrave;m hủy cũng c&oacute; mục đ&iacute;ch nhằm để giải ph&oacute;ng t&agrave;i nguy&ecirc;n trước khi tho&aacute;t ra khỏi chương tr&igrave;nh như đ&oacute;ng tệp, giải ph&oacute;ng bộ nhớ.</p> <p>Tương tự như h&agrave;m tạo, t&ecirc;n h&agrave;m hủy phải tr&ugrave;ng khớp ch&iacute;nh x&aacute;c với t&ecirc;n lớp. Khai b&aacute;o h&agrave;m hủy phải lu&ocirc;n bắt đầu bằng k&yacute; hiệu dấu ng&atilde; (~) như trong c&uacute; ph&aacute;p ở tr&ecirc;n.</p> <p><strong><em>C&uacute; ph&aacute;p:</em></strong></p> <pre class="language-markup"><code>~t&ecirc;n_lớp();</code></pre> <h2>Quy tắc đặt t&ecirc;n cho h&agrave;m hủy</h2> <ul> <li>T&ecirc;n phải bắt đầu bằng dấu ng&atilde; (~) v&agrave; phải tr&ugrave;ng với t&ecirc;n lớp.</li> <li>Kh&ocirc;ng được định nghĩa nhiều hơn một h&agrave;m hủy trong một lớp.</li> <li>H&agrave;m tạo c&oacute; thể c&oacute; c&aacute;c tham số, nhưng h&agrave;m hủy th&igrave; kh&ocirc;ng.</li> <li>H&agrave;m hủy kh&ocirc;ng trả về bất kỳ kiểu dữ liệu n&agrave;o.</li> <li>Khi h&agrave;m hủy kh&ocirc;ng được định nghĩa bởi người lập tr&igrave;nh trong một lớp, tr&igrave;nh bi&ecirc;n dịch sẽ tự động tạo một h&agrave;m hủy mặc định v&agrave; thực hiện n&oacute; khi kết th&uacute;c chương tr&igrave;nh.</li> <li>N&oacute; kh&ocirc;ng được ph&eacute;p khai b&aacute;o l&agrave; static, volatile hay const.</li> <li>H&agrave;m hủy n&ecirc;n được khai b&aacute;o trong phạm vi public của một lớp</li> </ul> <h2>Đặc điểm của h&agrave;m hủy</h2> <ul> <li>H&agrave;m hủy tự động được gọi khi đối tượng bị hủy hoặc tho&aacute;t khỏi phạm vi nhất định hoặc chương tr&igrave;nh kết th&uacute;c thực thi.</li> <li>N&oacute; kh&ocirc;ng thể được khai b&aacute;o l&agrave; static hoặc const.</li> <li>H&agrave;m hủy kh&ocirc;ng c&oacute; đối số.</li> <li>H&agrave;m hủy kh&ocirc;ng c&oacute; kiểu trả về giống với h&agrave;m tạo.</li> <li>Một h&agrave;m hủy phải được khai b&aacute;o với chỉ định quyền truy cập l&agrave; public của lớp.</li> <li>Người lập tr&igrave;nh kh&ocirc;ng thể truy cập địa chỉ của h&agrave;m hủy.</li> <li>H&agrave;m hủy c&oacute; thể được định nghĩa l&agrave;m h&agrave;m ảo (Virtual) trong một lớp cơ sở khi ta sử dụng một h&agrave;m ảo.</li> <li>H&agrave;m hủy kh&ocirc;ng được kế thừa.</li> </ul> <p>V&iacute; dụ về h&agrave;m hủy:</p> <pre class="language-cpp"><code>#include &lt;iostream&gt; using namespace std; class sinh_vien { private: int ID_sv; public: sinh_vien(int a) { ID_sv = a; } ~sinh_vien(){ cout &lt;&lt; "Doi tuong da bi huy" &lt;&lt; endl; } void in_thong_tin(){ cout &lt;&lt; "ID sinh vien la: " &lt;&lt; ID_sv &lt;&lt; endl; } }; int main() { sinh_vien sv(1); sv.in_thong_tin(); sinh_vien sv2 = sv; sv2.in_thong_tin(); return 0; }</code></pre> <p>Kết quả:</p> <pre class="language-markup"><code>ID sinh vien la: 1 ID sinh vien la: 1 Doi tuong da bi huy Doi tuong da bi huy</code></pre> <p>Trong v&iacute; dụ tr&ecirc;n, h&agrave;m hủy đ&atilde; được tự gọi sau khi ra khỏi phạm vi của h&agrave;m main() v&agrave; in ra kết quả l&agrave; "Doi tuong da bi huy".</p> <p><strong>Ch&uacute; &yacute;: Nếu ta kh&ocirc;ng viết h&agrave;m hủy trong một lớp, tr&igrave;nh bi&ecirc;n dịch sẽ tự động tạo một h&agrave;m hủy mặc định. H&agrave;m hủy mặc định sẽ hoạt động hiệu quả trừ khi ch&uacute;ng ta cấp ph&aacute;t bộ nhớ động cho con trỏ của một lớp. Khi một lớp chứa một con trỏ tới bộ nhớ được cấp ph&aacute;t động, ch&uacute;ng ta n&ecirc;n viết một h&agrave;m hủy để giải ph&oacute;ng bộ nhớ trước khi đối tượng của lớp bị hủy. Điều n&agrave;y phải được thực hiện để tr&aacute;nh r&ograve; rỉ bộ nhớ.</strong></p> <p>Tr&ecirc;n đ&acirc;y l&agrave; c&aacute;c kh&aacute;i niệm v&agrave; v&iacute; dụ cơ bản về h&agrave;m tạo v&agrave; h&agrave;m hủy C++. Hy vọng rằng mọi người c&oacute; thể &aacute;p dụng được v&agrave;o trong chương tr&igrave;nh của m&igrave;nh. Mọi người h&atilde;y tiếp tục theo d&otilde;i c&aacute;c b&agrave;i tiếp theo tr&ecirc;n <a href="http://tek4.vn">tek4</a> nh&eacute;!</p>