Để tránh giữ phải sử dụng ->
và thay vào đó làm việc trực tiếp với đối tượng, nó là thực hành chấp nhận được để làm:Nó được coi là phong cách tốt để dereference `new` con trỏ?
obj x = *(new obj(...));
...
delete &obj;
Để tránh giữ phải sử dụng ->
và thay vào đó làm việc trực tiếp với đối tượng, nó là thực hành chấp nhận được để làm:Nó được coi là phong cách tốt để dereference `new` con trỏ?
obj x = *(new obj(...));
...
delete &obj;
Đây không chỉ là thực hành kém, nhưng:
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;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.
Không, và trong thực tế điều này dẫn đến một sự rò rỉ. x
là sao 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ó).
Hoặc bạn có thể sử dụng tham chiếu 'obj & = (* new ...' – Marcin
@Marcin Bạn có thể, nhưng tại sao? –
@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. :) –
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ó.
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ỉ.
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ổ. –
@ JamesKanze: Vâng, thực sự là –
Vâng, người ta có thể làm 'obj & x = * new' ít nhất. –