cuốn sách gpt4 ai đã làm

Các hàm ảo C++ hoạt động kỳ lạ

In lại Tác giả: Vũ trụ không gian Thời gian cập nhật: 2023-11-04 14:41:13 25 4
mua khóa gpt4 Nike

Tôi đang cố gắng hiểu các chức năng ảo và kế thừa ảo. Trong hầu hết các phần, tôi nghĩ rằng tôi đã xử lý được nó và nó liên quan như thế nào đến tính đa hình, tôi đã đọc về cách vptr hoạt động với các đối tượng dẫn xuất, v.v., nhưng ví dụ sau đây khiến tôi thất vọng, đó là những gì Tôi đang làm môn Thuật toán và Cấu trúc dữ liệu trong Sách C++:

#include 
using namespace std;

lớp Lớp 1 {
public:
khoảng trống ảo f() {
cout << "Hàm f() trong Class1\n";
}

khoảng trống g() {
cout << "Hàm g() trong Class1\n";
}
};

lớp Lớp 2 {
public:
khoảng trống ảo f() {
cout << "Hàm f() trong Class2\n";
}

khoảng trống g() {
cout << "Hàm g() trong Class2\n";
}
};

lớp Lớp 3 {
public:
khoảng trống ảo h() {
cout << "Hàm h() trong Class3\n";
}
};

int chính() {
Đối tượng lớp11, *p;
đối tượng lớp22;
đối tượng lớp33;

p = &object1;
p->f();
p->g();

p = (Class1*) &object2;
p->f();
p->g();

p = (Class1*) &object3;
p->f(); // có thể chấm dứt chương trình một cách bất thường;
p->g();
// p->h(); // h() không phải là thành viên của Class1;
return 0;
}

Đầu ra:

Hàm f() trong Class1
Hàm g() trong Class1
Hàm f() trong Class2
Hàm g() trong Class1
Hàm h() trong Class3
Hàm g() trong Class1

Tôi hiểu mọi thứ trừ câu cuối cùngp->f(); .như lời nói đầu, tôi biết chúng ta không thể gọi trực tiếp h()từ PBởi vì loại được chuyển đổi thànhLớp 1loại, nhưng không nên Lớp 3 vptr chỉ trỏ đến các chức năng ảo h()trong vtable của nó, nếu vậy thì nó không nên tìm kiếm f()hiện hữulớp 3 vtable không tìm thấy nó? tại sao nó nghĩ Lớp1::f()ĐúngLớp3::h() , nó không giống nhưLớp 3继承自 Lớp 1 ...để ghi lại, nếu chúng ta viết lại Lớp 3trở nên:

class Class3 : public Class1 { // kế thừa công khai từ Class1 chỉ là sự khác biệt
public:
khoảng trống ảo h() {
cout << "Hàm h() trong Class3\n";
}
};

và chuyển đổi lên trên thành Lớp 1con trỏ rồi gọi p->f()nó mang lại cho chúng tôi Lớp1::f()Đúng như dự đoán, tôi chỉ không hiểu tại sao nó lại cho phép chúng tôi gọi p->f()khiLớp 3Không được kế thừa từ Lớp 1 .

câu trả lời hay nhất

Ví dụ nàykhông tốt, bạn đang chuyển đổi các loại không liên quan với nhau. Điều này dẫn đến hành vi không xác định.

Mã khai thác những điểm tương đồng về bố cục giả định giữa các loại đối tượng khác nhau. Vtable sẽ ở cùng một vị trí trong mọi đối tượng và các hàm ảo sẽ được tìm thấy theo chỉ mục thay vì tên. Vì vậy, đối với Lớp 1 Cuộc gọi đến hàm ảo đầu tiên sẽ tạo ra một cuộc gọi thông qua bảng, dẫn đến Lớp 3 Cuộc gọi hàm ảo đầu tiên. Hãy nhớ rằng đây chỉ là tai nạn và không được đảm bảo bởi bất kỳ tài sản nào của C++.

Về hành vi kỳ lạ của các hàm ảo C++, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/30488193/

25 4 0
không gian vũ trụ
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress