2012-02-23 36 views
25

file AhC++ Không xác định Tham khảo vtable và thừa kế

#ifndef A_H_ 
#define A_H_ 

class A { 
public: 
    virtual ~A(); 
    virtual void doWork(); 
}; 

#endif 

file Child.h

#ifndef CHILD_H_ 
#define CHILD_H_ 

#include "A.h" 

class Child: public A { 
private: 
    int x,y; 
public: 
    Child(); 
    ~Child(); 
    void doWork(); 
}; 
#endif 

Và Child.cpp

#include "Child.h" 

Child::Child(){ 
    x = 5; 
} 

Child::~Child(){...} 

void Child::doWork(){...}; 

Trình biên dịch nói rằng có một tài liệu tham khảo không xác định để vtable cho A. Tôi đã thử rất nhiều thứ khác nhau nhưng chưa ai làm việc.

Mục tiêu của tôi là dành cho lớp A làm Giao diện và tách riêng mã thực thi khỏi các tiêu đề.

+4

Bạn phải xác định mọi hàm ảo không thuần khiết mà bạn khai báo. Bạn không cần xác định hàm không phải ảo mà bạn khai báo nhưng không sử dụng. –

Trả lời

60

Tại sao lỗi & cách khắc phục?

Bạn cần cung cấp definitions cho tất cả các chức năng ảo trong class A. Chỉ các hàm ảo thuần túy mới được phép không có định nghĩa.

ví dụ: Trong class A cả các phương pháp:

virtual ~A(); 
virtual void doWork(); 

cần được xác định (nên có một cơ thể)

ví dụ:

A.cpp

void A::doWork() 
{ 
} 
A::~A() 
{ 
} 

Nên biết trước:
Nếu bạn muốn bạn class A để hoạt động như một giao diện (còn được gọi Abstract class trong C++) thì bạn nên thực hiện phương pháp tinh khiết ảo.

virtual void doWork() = 0; 

Tốt đọc:

What does it mean that the "virtual table" is an unresolved external?
When building C++, the linker says my constructors, destructors or virtual tables are undefined.

+0

Ý của bạn là gì? – rjmarques

+0

@ user1227351: Cập nhật câu trả lời để giải thích tốt hơn.Đọc các liên kết để được giải thích thêm. –

+0

Có ảo ~ A(); virtual void doWork() = 0; vẫn cung cấp lỗi vtable = /. Nhưng nếu không có destructor nó hoạt động tốt. Tuy nhiên không có nó, nếu tôi làm một cái gì đó như: A * a = new Child(); xóa a; rõ ràng nó sẽ không gọi Child :: ~ Child(). Có cách giải quyết nào không? – rjmarques

6

Mục tiêu của tôi là cho A là một giao diện, và để tách mã thực hiện từ đầu.

Trong trường hợp đó, làm cho chức năng thành viên như tinh khiết ảo trong lớp A.

class A { 
    // ... 
    virtual void doWork() = 0; 
}; 
+0

Điều đó loại bỏ lỗi nếu tôi cũng loại bỏ các destructor. Trong trường hợp đó nếu tôi làm: A a = new Child(); xóa a; nó sẽ gọi là gì? – rjmarques

+0

Tiêu hủy luôn theo thứ tự xây dựng ngược. Trong trường hợp này, class 'A' destructor phải là virtual thực thi' Destr 'Child' được gọi đầu tiên, tiếp theo là' A' destructor. Nếu destructor lớp 'A' không phải là ảo thì hành vi là không xác định. – Mahesh

+0

Nó sẽ gọi destructor của trẻ như bạn đã làm cho lớp cha destructor ảo. Sau đó, destructor của lớp cha. – Izza

1

Hãy chắc chắn để xóa bất kỳ tập tin "* .gch" nếu không ai trong số các câu trả lời khác giúp bạn.

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