Tiêu chuẩn ISO C ++ quy định rằng tất cả các phương thức ảo của một lớp không thuần ảo phải được xác định.
Nói một cách đơn giản quy tắc là:
Nếu lớp dẫn xuất của bạn vượt quá phương thức ảo của lớp Cơ sở thì nó cũng phải cung cấp một định nghĩa, Nếu không thì lớp Cơ sở sẽ cung cấp định nghĩa của phương thức đó.
Theo quy tắc trên trong ví dụ mã của bạn, virtual void bar();
cần một định nghĩa trong lớp Cơ sở.
Tài liệu tham khảo:
C ++ 03 Tiêu chuẩn: 10.3 Hàm ảo [class.virtual]
Một hàm ảo được khai báo trong một lớp sẽ được định nghĩa, hoặc được khai báo thuần túy (10.4) trong lớp đó, hoặc cả hai; nhưng không cần chẩn đoán (3.2).
Vì vậy, bạn nên làm cho hàm thuần ảo hoặc cung cấp một định nghĩa cho nó.
Tài liệu về gcc faq cũng vậy:
Tiêu chuẩn ISO C ++ chỉ định rằng tất cả các phương thức ảo của một lớp không thuần ảo phải được xác định, nhưng không yêu cầu bất kỳ chẩn đoán nào đối với các vi phạm quy tắc này [class.virtual]/8
. Dựa trên giả định này, GCC sẽ chỉ phát ra các hàm tạo được xác định ngầm, toán tử gán, hàm hủy và bảng ảo của một lớp trong đơn vị dịch xác định phương thức phi nội tuyến đầu tiên của nó.
Do đó, nếu bạn không xác định được phương pháp cụ thể này, trình liên kết có thể phàn nàn về việc thiếu định nghĩa cho các ký hiệu dường như không liên quan. Rất tiếc, để cải thiện thông báo lỗi này, có thể cần phải thay đổi trình liên kết và điều này không phải lúc nào cũng thực hiện được.
Giải pháp là đảm bảo rằng tất cả các phương thức ảo không thuần túy đều được xác định. Lưu ý rằng hàm hủy phải được định nghĩa ngay cả khi nó được khai báo là thuần ảo [class.dtor]/7
.