2012-06-29 41 views
11

Tôi đang cố gắng hiểu một điểm ở đây trong C++. Nếu lớp A có phương thức không ảo, và lớp B, mở rộng A, ghi đè phương thức đó, tôi có thể tạo một thể hiện của B và bằng cách nào đó sử dụng phương thức được định nghĩa trong B không? Có một điểm nào để ghi đè phương thức không phải ảo không?Tôi có thể sử dụng phương pháp ghi đè phương pháp phi ảo không?

+1

Những gì bạn mô tả được gọi là * ẩn *, không ghi đè. Hãy xem ở đây, ví dụ: http://stackoverflow.com/questions/2161462/c-inheritance-and-function-overriding – jrok

Trả lời

31

Có một điểm để ghi đè lên một phương pháp phi ảo không?

Bạn đang không thực sự trọng, nhưng đây là hành vi, tức là

B* b = new B(); 
A* a = new B(); 
b->method(); //Calls B's method 
a->method(); // Calls A's method 

Vì vậy, các loại con trỏ/tham khảo xác định phương pháp gọi.

tôi có thể tạo phiên bản B và bằng cách nào đó sử dụng phương thức được xác định trong B không?

Có. Con trỏ/kiểu tham chiếu phải thuộc kiểu B. (xem ví dụ trước).

Nếu bạn không khai báo methodvirtual, bạn không thể ghi đè nó, nhưng bạn có thể ẩn nó.

+0

Câu trả lời tuyệt vời, cảm ơn – Eyal

+1

Một "gotcha" là tình huống khi 'A' lần lượt xuất phát từ một số lớp cơ sở (hoặc thực hiện một giao diện) khai báo phương thức' ảo '() ', trong trường hợp đó phương thức' a->() 'trên thực tế sẽ gọi' B.method() '... – BadCash

+0

@Chip Bạn đã bỏ lỡ nhấn mạnh sự khác biệt. Câu trả lời này chỉ hoàn thành với nhận xét của BadCash. – ManuelSchneid3r

9

Nếu B thừa hưởng từ A, và định nghĩa lại một phương pháp quy định tại A, sau đó trường hợp mới của B sẽ gọi phiên bản B 's. Tuy nhiên, nếu phương pháp không phải là ảo, thì không có hành vi đa hình, vì vậy nếu một thể hiện của B được tham chiếu là A, thì phương thức sẽ là A. Ví dụ:

struct A { 
    void foo() { std::cout << "A::foo" << std::endl; } 
}; 

struct B : public A { 
    void foo() { std::cout << "B::foo" << std::endl; } 
}; 

B b; 
b.foo(); 
A *a = &b; 
a->foo(); 

Sản lượng của các mã trên sẽ là:

B::foo 
A::foo 

Tuy nhiên, nếu phương pháp foo đã ảo, sau đó B::foo sẽ được in hai lần.

+0

Cũng được viết! :) – niknak

2

Nếu một chức năng không phải là virtual sau đó kiểu của biến xác định thực hiện là phái quá:

#include <iostream> 

using namespace std; 

struct A { 
    void f() { cout << "A" << endl; } 
}; 

struct B : public A { 
    void f() { cout << "B" << endl; } 
}; 

int main(int args, char** argv) { 

    B b; 
    A& a = b; 

    b.f(); 
    a.f(); 

    return 0; 
} 
0
  • Không, không có cơ chế để ghi đè lên một phương pháp không ảo trong lớp A.
  • có, bạn có thể sử dụng một phương pháp không ảo từ lớp một quá tải trong B bằng cách sử dụng độ phân giải phạm vi điều hành A :: methodName
Các vấn đề liên quan