2012-01-31 34 views
14

Tôi đang đọc Effective C++ và đã xem qua ví dụ này:Tại sao static_cast (* này) thành một lớp cơ sở tạo một bản sao tạm thời?

class Window {        // base class 
public: 
    virtual void onResize() { ... }    // base onResize impl 
    ... 
}; 

class SpecialWindow: public Window {   // derived class 
public: 
    virtual void onResize() {     // derived onResize impl; 
    static_cast<Window>(*this).onResize(); // cast *this to Window, 
               // then call its onResize; 
               // this doesn't work! 

    ...          // do SpecialWindow- 
    }           // specific stuff 

    ... 

}; 

Cuốn sách này nói:

Những gì bạn có thể không mong đợi là nó không gọi hàm trên đối tượng hiện tại ! Thay vào đó, các diễn viên tạo ra một bản sao mới, tạm thời của phần cơ sở lớp * này, sau đó gọi onResize trên bản sao!

Tại sao static_cast (ở trên mã) tạo bản sao mới? Tại sao không chỉ sử dụng phần lớp cơ sở của đối tượng?

+0

Nếu nó được truyền tới 'static_cast (* this) .onResize();', thì tôi nghĩ nó sẽ sử dụng đối tượng hiện tại. (Lưu ý '&'). Không chắc chắn mặc dù. –

+0

static_cast (this) -> onResize(); cũng sẽ hoạt động nhưng tất nhiên là Window :: onResize(); là đúng ở đây. – Trass3r

Trả lời

25

Vì mã này yêu cầu để tạo đối tượng mới. Mã này muốn tạo đối tượng Window từ *this - có thể được thực hiện bằng cách sử dụng công cụ sao chép sao chép của Window.

gì bạn muốn thay vì đây là:

static_cast<Window&>(*this).onResize(); 
//    ^
//    note the & 

này có nghĩa là tôi muốn thực hiện một Window& từ *this - đó là một chuyển đổi ngầm từ một có nguồn gốc lớp tham khảo (*this là một số SpecialWindow&) đến tham chiếu Window&.

Tuy nhiên, nó tốt hơn để chỉ gọi phiên bản cụ thể của hàm thành viênonResize() bạn muốn gọi:

Window::onResize(); // equivalent to this->Window::onResize(); 
2

Bởi vì bạn đang đúc tượng thực tế không phải là một con trỏ hoặc tham chiếu. Cũng giống như cách truyền double đến int tạo mới int - không sử dụng lại một phần của double.

6

Đó là do mã được truyền tới giá trị Window thay vì tham chiếu Window&. Theo tiêu chuẩn, hình thức đúc tương đương với gọi (C++ 11 §5.2.9/4 = C++ 03 §5.2.9/2)

Window __t (*this); 
__t.onResize(); 

mà gọi là sao chép constructor của Window và thực hiện onResize trên bản sao đó.

(Cách đúng đắn của cách gọi một phương pháp của lớp cha là

Window::onResize(); 

)

1

Contrast:

static_cast<Window>(*this) 

với:

static_cast<Window&>(*this) 

Một gọi là bản sao constructor, d khác không. cái đó có giúp ích không?

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