2016-02-10 10 views
5

Sử dụng cú pháp vị trí mới, tôi sẽ có thể làm điều gì đó như thế này:Làm thế nào để xác định xem đối tượng đã được đặt sử dụng vị trí mới

char *buffer = new char[sizeof(MyClass)]; //pre-allocated buffer 
MyClass *my_class = new (buffer) MyClass; //put da class there 

Bây giờ giả sử tôi chỉ làm dòng đầu tiên, nhưng không phải là thứ hai . Có cách nào mà nó có thể được xác định trong mã cho dù bộ đệm đã được phân bổ một cách thích hợp, nhưng không có đối tượng của loại MyClass vẫn chưa được khởi tạo ở đó?

+2

Tại sao bạn cần điều này? Nó có vẻ không đúng. – ZDF

+0

@ZDF Khi nó quay ra, khi tôi nhìn vào vấn đề chặt chẽ hơn nó quay ra tôi có khả năng không. Vì vậy, câu trả lời cho câu hỏi của bạn có vẻ khá rõ ràng - thiếu kinh nghiệm ... :) – Bitrex

Trả lời

1

đang Original:

char *buffer = new char[sizeof(MyClass)]; //pre-allocated buffer 
MyClass *my_class = new (buffer) MyClass; //put da class there 

Để xác định động biết vị trí new đã được thực hiện thông tin về nó phải được lưu trữ ở đâu đó. Ngôn ngữ không cung cấp dịch vụ đó. Vì vậy, bạn phải tự mình làm theo một trong hai cách chính có thể:

  • Lưu trữ thông tin trong bộ đệm.
    Đối với trường hợp này bộ đệm phải được khởi tạo khi phân bổ. Ví dụ. chỉ cần thêm () vào cuối biểu thức new của bạn. Nếu không, không có cách nào để đảm bảo rằng nội dung bộ đệm không giống như một đối tượng. Hai trường hợp phụ:
    1. Bằng cách thêm phòng cho cờ trong bộ đệm.
    2. Bằng cách gắn cờ làm thành viên của đối tượng.
      Trong trường hợp của một lớp đa hình, trong thực tế sẽ là một con trỏ vtable khác không, có thể dùng làm cờ.
  • Lưu trữ thông tin bên ngoài.
    Đối với trường hợp này, bộ đệm không cần phải được khởi tạo khi phân bổ.Có một tỷ cộng với một số khả năng, bao gồm
    1. Biến đơn giản bool.
    2. Một bộ sưu tập các con trỏ tới tất cả các đối tượng như vậy.
    3. Tín hiệu âm thanh phát ra với tinh tinh, sau đó được truy vấn.
4

Ngôn ngữ không cung cấp bất kỳ cơ chế tích hợp nào để cung cấp thông tin đó, ít nhất là không có thông tin nào tôi biết. Bạn sẽ phải thêm mã sổ sách kế toán của riêng mình để theo dõi thông tin đó.

1

Bạn có thể duy trì một bảng static của this giá trị con trỏ mà bạn biến đổi trong các hàm tạo và hàm hủy thành MyClass. Sau đó kiểm tra điều này với một giá trị cụ thể của buffer khi bạn cần.

Đừng quên xem xét hậu quả của ngữ nghĩa di chuyển. Sẽ khó khăn để có được quyền.

2

Đối với mục đích gỡ lỗi, bạn có thể thêm một thành viên đặc biệt signature-MyClass và đặt giá trị là một hằng số

class MyClass { 
    public: 
     MyClass() : signature(762347562374) {} 
     bool isValidSignature() const { return signature==762347562374; } 
    private: 
     unsigned long long signature; 
     <other members> 
}; 

Sau đó, kiểm tra xem nó như sau:

char *buffer = new char[sizeof(MyClass)]; //pre-allocated buffer 
MyClass *my_class = new (buffer) MyClass; //put da class there 
if (my_class->isValidSignature()) 
    <this means that the object has been allocated correctly, with a high probability> 
} 

Bạn có thể đặt tất cả mọi thứ đó là liên quan đến chữ ký, bên trong một #ifdef thích hợp để chỉ chạy trong chế độ gỡ lỗi.

+0

Tại sao một người nên sử dụng cách tiếp cận thống kê khi một lá cờ mang lại hành vi được bảo đảm? –

+0

@ Cheersandhth.-Alf Có vẻ như có một số giải pháp tầm thường cho vấn đề mà bạn đang nói đến. Tôi không hiểu; có lẽ bạn nên thêm một câu trả lời để giải thích ý bạn là "cờ". – anatolyg

+0

Tôi ghét các lớp có kích thước khác (lớn hơn) trong gỡ lỗi xây dựng –

1

Không phải không tự mình theo dõi.

Một giải pháp sẽ là tạo trình bao bọc xung quanh std::allocator.

template<class T> 
class MyAllocator 
{ 
public: 
    T* allocate(std::size_t count = 1) 
    { 
     return allocator_.allocate(count); 
    } 

    template<class... Args> 
    void construct(T* ptr, Args&&... args) 
    { 
     allocator_.construct(ptr, std::forward<Args>(args)...); 
     allocated_ = true; 
    } 

    bool IsAllocated() const 
    { 
     return allocated_; 
    } 

private: 
    std::allocator<T> allocator_; 
    bool allocated_; 

}; 
+0

Điều này so sánh với chỉ một biến 'bool' trực tiếp như thế nào? –

+0

Chỉ cần nghĩ rằng đó là một cách tốt đẹp để kết thúc mọi thứ. –

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