2015-04-24 13 views
11

Thực ra tôi đang nghĩ về các đối tượng có thể bị phá hủy tầm thường, không chỉ về POD (Tôi không chắc POD có thể có lớp cơ sở).Có an toàn khi xóa đối tượng POD bằng con trỏ tới cơ sở của nó không?

Khi tôi đọc lời giải thích này cho is_trivially_destructible từ cppreference Tôi nhận thấy điều này:

lưu trữ bị chiếm đóng bởi các đối tượng trivially phá hủy có thể được tái sử dụng mà không gọi destructor.

Vì vậy, nó là an toàn để làm điều đó:

struct A { 
    int a; 
}; 
struct B : A { 
    int b; 
}; 
int main() { 
    A* a = new B; 
    delete a; 
} 

B::~B() sẽ không được gọi là - và AFAIK (hãy sửa nếu tôi sai) toàn bộ bộ nhớ sẽ được giải phóng. Và B::~B() chắc chắn là tầm thường.

tôi biết mã này có mùi nặng, nhưng câu hỏi của tôi là chỉ về tính an toàn của mã này ...

+0

Bạn có chắc chắn rằng 'a' sẽ luôn trỏ đến một thể hiện' B' và 'B' sẽ vẫn còn bị phá hủy không đáng kể? Nếu ai đó sửa đổi 'B' hoặc thay thế nó bằng một lớp con không bị phá hủy của' B', anh ta sẽ âm thầm giới thiệu một lỗi. – Kos

+0

Tôi không hoàn toàn có được điểm mà bạn đang hướng đến. Nếu bạn muốn tái sử dụng một đối tượng phân bổ heap, bạn sẽ không giải phóng bộ nhớ heap (đi cùng với cuộc gọi xóa) nhưng bạn sẽ giữ cho cá thể không được sử dụng trong một số loại thùng chứa tái chế thay vì gọi xóa nó. Bạn cũng có thể có một phương thức "factory" để có được một cá thể, mà trước tiên sẽ cố gắng tái chế các cá thể cũ trước khi nó tạo ra các cá thể mới với mới. – BitTickler

+0

Scratch bài đăng trước của tôi lol. Ông hỏi về việc liệu anh ta có cần một destructor ảo mà không bao giờ sử dụng những từ đó không :) – BitTickler

Trả lời

18

Không, đây không được phép. [Expr.delete]/p3, tôi nhấn mạnh:

Trong phương án đầu tiên (xóa đối tượng), nếu loại tĩnh của đối tượng bị xóa là khác biệt so với loại động của nó, là tĩnh loại sẽ là lớp cơ sở của loại động của đối tượng là bị xóa và loại tĩnh sẽ có một destructor ảo hoặc hành vi không xác định.

Thực tế, ủy ban gần đây là rejecteda proposal to make deleting a POD via a pointer-to-base well-defined.

+2

Có lẽ đáng nói đến là liệu gọi một cách rõ ràng ':: operator delete (a)' là một giải pháp hợp lệ. Theo như tôi thấy, điều đó sẽ hợp lệ. Tuy nhiên, tôi sẽ không khuyên bạn nên, nếu có bất kỳ khả năng nào mà 'delete a;' thực sự sẽ gọi là một toán tử 'delete' khác. – hvd

Các vấn đề liên quan