2012-04-02 32 views
6

Tôi khá mới đối với C++, nhưng tôi đã gặp phải vấn đề mà tôi không thể giải quyết được. Tôi sẽ sử dụng ô tô để minh họa vấn đề, chỉ để làm mọi thứ dễ dàng hơn. Được rồi, vì vậy hãy nói rằng tôi có một chiếc xe cơ sở, và tôi có những thương hiệu khác nhau được kế thừa từ lớp đó. Giống như vậy:C++ Gọi hàm xuất phát từ cá thể lớp cơ sở

class Car 
{ 
    public: 
     Car(); 
}; 

class Ford: public Car 
{ 
    public: 
     Ford(); 
     void drive(); 
     void park(); 
}; 

Toàn bộ ý tưởng là đặt tất cả những chiếc xe khác nhau này lại với nhau trong một véc tơ thuộc loại Xe hơi. Giống như vậy:

vector<Car*> cars; 
cars.push_back(new Ford()); 
cars.back()->drive(); //this won't work 

Làm cách nào tôi có thể gọi hàm dẫn xuất trên cá thể lớp cơ sở? Lưu ý rằng tôi muốn đặt tất cả trong một vector duy nhất. Lý do đằng sau điều này là bởi vì tôi chỉ muốn sử dụng thể hiện lớp xe có nguồn gốc cuối cùng đã được thêm vào. (Trong trường hợp này lớp xe dẫn xuất là ford). Cũng lưu ý rằng tất cả các lớp học xe hơi sẽ có cùng chức năng.

Trả lời

7

Nếu các chức năng này thực sự phổ biến với tất cả các lớp dẫn xuất, thì bạn có một giao diện chung, vì vậy bạn nên thể hiện điều này thông qua lớp cơ sở. Để làm như vậy, bạn khai báo các chức năng như thuần ảo:

class Car { 
public: 
    virtual void drive() = 0; // Pure-virtual function 
}; 

class Ford : public Car { 
public: 
    virtual void drive() { std::cout << "driving Ford\n"; } 
}; 

... 

vector<Car*> cars; 
cars.push_back(new Ford()); 
cars.back()->drive(); //this will work 

[Trên một mặt lưu ý, nó thường được coi thực hành kém để có một vector của con trỏ nguyên, bởi vì nó làm cho quản lý bộ nhớ khéo léo. Bạn nên cân nhắc sử dụng con trỏ thông minh.]

+0

Cảm ơn rất nhiều phản ứng tuyệt vời và nhanh chóng, điều này đã làm các trick. – Dan

2

Nếu tất cả Car lớp có chức năng tương tự sau đó tuyên bố họ là tinh khiết virtual trong lớp cơ sở Car:

class Car 
{ 
public: 
    Car(); 
    virtual ~Car(); 
    virtual void drive() = 0; 
    virtual void park() = 0; 
}; 

này sẽ cho phép các mã ví dụ sử dụng vector để làm việc như đăng.

0

Có thể nếu có thể bạn có thể xác định lớp cơ sở như

class Car 
{ 
    public: 
     Car(); 
     virtual void drive(); 
}; 
0

Bạn phải xác định các giao diện như:

class Car{ 
public: 
Car(); 
virtual void moveForward(unsigned int speed) = 0; 
virtual void moveBack(unsigned int speed) = 0; 
//... 
virtual ~Car(); 
}; 

Đừng quên để làm cho destructor ảo. Sau đó bạn chỉ cần thực hiện các phương pháp này trong các lớp học của con bạn, và gọi chúng sau. Cũng trong vectơ bạn có thể sử dụng shared_ptr hoặc chỉ truyền trực tiếp các cá thể.

3

Bạn có hai tùy chọn: hoặc đặt một phương thức ổ đĩa ảo() trong Định nghĩa ô tô của bạn hoặc truyền con trỏ Xe đến con trỏ của Ford. Rất có thể bạn sẽ muốn làm việc đầu tiên.

class Car 
{ 
    public: 
     Car(); 
     virtual void drive() { // default implementation} 
}; 

Bây giờ bạn có thể lái xe() Xe của bạn! Bạn cũng có thể biến drive() thành một hàm ảo thuần túy, như vậy:

class Car 
{ 
    public: 
     Car(); 
     virtual void drive() = 0; 
}; 

Điều này về cơ bản có nghĩa là không có triển khai mặc định cho ổ đĩa(): PHẢI được thực hiện lại trong phân lớp.Cách thứ hai tôi đã đề cập, trong đó, một lần nữa, có thể bạn không muốn, nhưng nên được bao gồm cho đầy đủ, là để đúc con trỏ:

static_cast<Ford*>(cars.back())->drive(); 

này chỉ hoạt động nếu bạn biết trước rằng xe là một chiếc Ford tuy nhiên, và không được sử dụng nhiều trong kịch bản này. Bạn cũng có thể xem xét dynamic_cast.

+0

Vâng, tôi sẽ sử dụng phương pháp đầu tiên, nhưng thật tuyệt khi biết rằng có một cách khác. Cảm ơn bạn về thông tin! – Dan

+0

@Anthony, tôi nghĩ rằng đối với phương pháp thứ hai nó sẽ là tốt hơn để sử dụng một dyanamic_cast thay vì một static_cast – exs

0

Bạn phải đặt một chức năng ảo.

Một chức năng ảo trong lớp cơ sở. Một chức năng ảo có thể được thực hiện trong lớp phụ, vì vậy bạn có thể chuyên hành vi của ổ đĩa() chẳng hạn.

Bạn có thể tìm thấy một faq (hoặc hướng dẫn) về chức năng ảo ở đây:

http://www.parashift.com/c++-faq-lite/virtual-functions.html

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