2012-05-22 46 views
17

Tôi hiểu tại sao điều này xảy ra, nhưng tôi đang cố gắng giải quyết nó ... đây là những gì mã của tôi đang thực hiện khi lỗi được tạo ra (do đó dẫn đến sự cố) khi chương trình của tôi ra khỏi ...Cách giải quyết "phương pháp ảo thuần túy được gọi là"

pure virtual method called

SomeClass::~SomeClass() 
{ 
    BaseClassObject->SomePureVirtualMethod(this); 
} 

void DerivedClass::SomePureVirtualMethod(SomeClass* obj) 
{ 
    //Do stuff to remove obj from a collection 
} 

tôi chưa bao giờ có một cuộc gọi đến new SomeClass nhưng tôi có một QList<SomeClass*> mà tôi thêm SomeClass* đối tượng. Mục đích của destructor này trong SomeClass là để nói DerivedClass để loại bỏ một trường hợp cụ thể của SomeClass từ bộ sưu tập của nó là QList<SomeClass*>.

Vì vậy, trong một ví dụ cụ thể ...

BaseClass = Shape

DerivedClass = Triangle

SomeClass = ShapeProperties công ty sở hữu một tham chiếu đến Shape

Vì vậy, tôi không bao giờ có một hãy gọi tới số new ShapeProperties nhưng tôi có một QList<ShapeProperties*> bên trong của Triangle. Các destructor trong ShapeProperties là để nói Triangle để loại bỏ một tài sản cụ thể của ShapeProperties từ bộ sưu tập của nó là QList<ShapeProperties*>.

Trả lời

28

Khi thời gian hủy của bạn được gọi, hàm hủy của các lớp kế thừa đã được gọi. Trong các hàm tạo và hàm hủy, kiểu động của đối tượng có thể được coi là giống như kiểu tĩnh. Đó là, khi bạn gọi các phương thức ảo từ bên trong các constructor/destructors của bạn, nó không phải là các phiên bản overriden của chúng được gọi.

Nếu SomePureVirtualMethod cần được gọi tại trình hủy, bạn sẽ phải gọi nó trong trình hủy của lớp nơi định nghĩa thực tế của phương thức bạn muốn.

+0

Sau đó, làm thế nào để tôi biết được trường hợp nào của 'this' tôi đang đề cập đến nếu tôi gọi nó bằng trong hàm khởi tạo có nguồn gốc? – user869525

+0

@ user869525: Bạn có thể thử lặp lại điều đó không? Tôi không hiểu ... –

+0

Tôi có thể hiểu lầm điều này, "Nếu' SomePureVirtualMethod' cần phải được gọi tại destructor, thì bạn sẽ phải gọi nó bên trong destructor của lớp nơi định nghĩa thực sự của phương thức bạn muốn. " – user869525

8

Khi bạn gọi phương thức virtual trong destructor của lớp cơ sở SomeClass nó gọi phương thức (SomePureVirtualMethod()) của lớp cơ sở SomeClass mà là một phương pháp ảo thuần tuý không có định nghĩa. Và do đó lỗi.

Tại sao điều này xảy ra?
Loại this trong hàm tạo hoặc hàm hủy là kiểu có hàm tạo hoặc hàm hủy đang được gọi và do đó công văn động không hoạt động trong các hàm tạo và hàm hủy như bạn mong đợi nó hoạt động trong tất cả các hàm khác.

Tại sao nó gặp sự cố?
Vì gọi một hàm ảo thuần túy từ hàm tạo hoặc hàm hủy là Hành vi không xác định.

C++ 03 10.4/6 tiểu bang

"Hàm thành viên có thể được gọi từ hàm tạo (hoặc hàm hủy) của lớp trừu tượng; hiệu ứng thực hiện trực tiếp hoặc gián tiếp đối tượng được tạo ra (hoặc bị phá hủy) từ một constructor (hoặc destructor) như vậy là không xác định. "

Làm cách nào để tránh?
Chỉ cần đảm bảo rằng bạn không gọi hàm ảo thuần túy từ hàm tạo hoặc hàm hủy.
Không gọi virtual phương thức trong hàm tạo hoặc hàm hủy trừ khi bạn hiểu động lực liên quan.