Giả sử rằng tất cả các lớp của một hệ thống phân cấp thực hiện chức năng thành viên mẫu g
. Tất cả các lớp chia sẻ việc thực hiện cùng hai chức năng khác f1
và f2
mà gọi mẫu này:Gọi hàm đa hình không có mã trùng lặp
struct A {
virtual void f1() {
g(5);
}
virtual void f2() {
g(5.5);
}
private:
template <typename T> void g(T) {std::cout << "In A" << std::endl;}
};
struct B: A {
// Can I get rid of this duplicate code?
virtual void f1() {
g(5);
}
virtual void f2() {
g(5.5);
}
private:
template <typename T> void g(T) {std::cout << "In B" << std::endl;}
};
struct C: A {
// Can I get rid of this duplicate code?
virtual void f1() {
g(5);
}
virtual void f2() {
g(5.5);
}
private:
template <typename T> void g(T) {std::cout << "In C" << std::endl;}
};
int main()
{
B b;
A &a = b;
a.f1();
return 0;
}
Kể từ khi triển khai của f1
và f2
là giống hệt nhau trong tất cả các lớp học, làm thế nào tôi có thể thoát khỏi các mã trùng lặp và vẫn có các cuộc gọi đa hình trong main
hoạt động như mong đợi (tức là tạo ra đầu ra "Trong B")?
Tôi nhìn theo cách khác: tất cả đều gọi 'this-> g ', trong đó' * this' là loại động của 'a'. Tại sao đây là cách nhìn sai? –
AlwaysLearning
@AlwaysLearning Vì 'g' không phải là (và không thể là) ảo, có nghĩa là các quy tắc biên dịch bình thường áp dụng cho nó. Lưu ý rằng các quy tắc biên dịch thời gian là mặc định trong C++. Chỉ có một vài ngoại lệ rõ ràng được chọn cho điều này ('virtual',' dynamic_cast', 'typeid'). – Angew
Phải. Nhưng 'f1' là ảo. Trong 'f1' kiểu' this' này là kiểu động của 'a'. Tất cả những gì tôi muốn là phải thực hiện giống hệt nhau của 'f1' trong lớp dẫn xuất mà không cần phải lặp lại việc thực hiện ... – AlwaysLearning