2013-05-13 30 views

Trả lời

29

Đây không chỉ là thực hành kém, nhưng:

  1. Rò rỉ bộ nhớ (rất có thể, trừ khi bạn đang sử dụng một số mô hình đó không phải là có thể nhìn thấy từ mã mà bạn cung cấp), vì obj sẽ lưu trữ một bản sao của đối tượng gốc được tạo bởi biểu thức new và con trỏ tới đối tượng đó được trả về bởi new bị mất;
  2. Quan trọng nhất, hành vi không xác định, vì bạn đang chuyển đến delete con trỏ đến đối tượng không được phân bổ với new. Mỗi đoạn 5.3.5/2 của C++ 11 Tiêu chuẩn:

[...] Trong phương án đầu tiên (xóa đối tượng), giá trị của toán hạng của xóa có thể là một con trỏ null giá trị, con trỏ tới đối tượng không phải mảng được tạo bởi một biểu thức mới mới hoặc con trỏ tới một đối tượng con (1.8) đại diện cho một lớp cơ sở của đối tượng như vậy (Điều 10). Nếu không, hành vi là không xác định.

+1

Và kèn thứ hai là người đầu tiên. Anh ta sẽ không bị rò rỉ bộ nhớ, bởi vì chương trình có lẽ sẽ không chạy đủ lâu để anh ta làm nhiều hơn một phân bổ. –

+0

@ JamesKanze: Vâng, thực sự là –

+1

Vâng, người ta có thể làm 'obj & x = * new' ít nhất. –

8

Không, và trong thực tế điều này dẫn đến một sự rò rỉ. xsao chép được khởi tạo, vì vậy đối tượng gốc được trỏ đến bởi new obj bị mất.

Chỉ cần sử dụng

obj x(...); 

Không cần để phân bổ động. Hoặc

obj x = obj(...); 

nếu bạn phải (nghi ngờ nó).

+2

Hoặc bạn có thể sử dụng tham chiếu 'obj & = (* new ...' – Marcin

+0

@Marcin Bạn có thể, nhưng tại sao? –

+4

@Marcin có, bạn có thể. Bạn cũng có thể đập bàn phím vào màn hình của mình. , không có nghĩa là bạn nên. :) –

7

Chắc chắn là không; sao chép đối tượng động vào một biến tự động, mất con trỏ duy nhất cho nó, và sau đó cố gắng xóa bản sao tự động. Bạn đã bị rò rỉ bộ nhớ và xóa không hợp lệ.

Tốt hơn nhiều là sử dụng một biến tự động ở nơi đầu tiên:

obj x(...); 
... 
// no need to delete anything 

hoặc, nếu nó thực sự phải động vì một lý do (vì nó là quá lớn đối với chồng, hoặc bạn không luôn muốn tiêu diệt nó ở đây), sau đó sử dụng một con trỏ thông minh, và một tài liệu tham khảo nếu bạn thực sự không thích ->

std::unique_ptr<obj> p(new obj(...)); 
obj & x = *p; 
... 
// still no need to delete anything 

Thay đổi của bạn x thành một tài liệu tham khảo sẽ là hợp lệ (miễn là bạn đang cẩn thận đó ngoại lệ, trả về hàm sớm, v.v. gây ra một rò rỉ), nhưng sẽ gây ra tiếng lú lẫn lộn giữa bất cứ ai không may, đủ để phải duy trì nó.

0

Bạn không thể xóa đối tượng của mình đúng cách nếu bạn làm như vậy.

Ngụ nhiên bạn làm như sau.

class A 
{ 
public: 
    int test (void) { return 1; } 
}; 

int main (void) 
{ 
    A * p = new A; 
    A v(*p); 
    //... 
    delete &v; // &v != p and v is not constructed via new! 
    return 0; 
} 

Nếu bạn muốn làm việc với cú pháp giống như đối tượng, bạn có thể ràng buộc tham chiếu đến đối tượng.

class A 
{ 
public: 
    int test (void) { return 1; } 
}; 

int main (void) 
{ 
    A * p = new A; 
    A & r = *p; 
    int i = r.test(); 
    delete p; 
    return 0; 
} 

Nếu bạn xóa đối tượng của mình thông qua cùng một con trỏ, sẽ không bị rò rỉ.