2012-04-11 11 views
11

Tôi đã gặp một số vấn đề ngoại lệ không rõ ràng với tôi. Trong C++, khi một đối tượng được ném, nó được sao chép lần đầu tiên vào một đối tượng tạm thời, và đối tượng tạm thời sau đó được chuyển tới mã đánh bắt. Bản sao liên quan đến việc sử dụng hàm tạo bản sao lớp của đối tượng. AFAIK, điều này có nghĩa là nếu một lớp có một hàm tạo bản sao riêng, nó không thể được sử dụng như một ngoại lệ. Tuy nhiên, trong VS2010, mã sau đây biên dịch và chạy:Có thể ném đối tượng với các nhà xây dựng bản sao riêng tư không?

class Except 
{ 
    Except(const Except& other) { i = 2; } 
public: 
    int i; 
    Except() : i(1) {} 
}; 

int main() 
{ 
    try 
    { 
     Except ex1; 
     throw ex1;   // private copy constructor is invoked 
    } 
    catch (Except& ex2) 
    { 
     assert(ex2.i == 2); // assert doesn't yell - ex2.i is indeed 2 
    } 
    return 0; 
} 

Điều này có hợp pháp không?

+0

Hãy thử thêm bản in hoặc gỡ lỗi và xem thứ tự các cuộc gọi, có thể mọi thứ không thực hiện chính xác như bạn nghĩ. – selalerer

+1

Tôi nhận được cùng một hành vi với VS2010 nhưng nó không thành công [ở đây] (http://ideone.com/RlOjl) với gcc v4.3.4. – hmjd

+0

Có thể là đối tượng tạm thời được xây dựng và bản sao được tối ưu hóa. Tương tự như tối ưu hóa giá trị trả lại. –

Trả lời

13

Nó không hợp pháp. Chuẩn 15,1/5

Nếu việc sử dụng các đối tượng tạm thời có thể được loại bỏ mà không thay đổi ý nghĩa của chương trình trừ việc thực hiện của nhà thầu và destructor gắn liền với việc sử dụng các đối tượng tạm thời (12,2), thì ngoại lệ trong trình xử lý có thể được khởi tạo trực tiếp với đối số của biểu thức ném. Khi đối tượng được ném là đối tượng lớp và trình tạo bản sao được sử dụng để khởi tạo bản sao tạm thời không thể truy cập được, chương trình bị lỗi (ngay cả khi đối tượng tạm thời có thể bị loại bỏ). Tương tự, nếu không thể truy cập được destructor cho đối tượng đó, chương trình là không đúng định dạng (ngay cả khi đối tượng tạm thời khác có thể bị loại bị loại bỏ).

+0

Wow thật tuyệt vời, không bao giờ có thể đoán được nó có thể xảy ra. cảm ơn bạn. – petric

2

Không, không phải.

15.1.5 Khi đối tượng ném là một đối tượng lớp, sao chép/di chuyển constructor và destructor sẽ có thể truy cập, ngay cả khi hoạt động sao chép/di chuyển được elided