2015-12-20 16 views
5

Sau khi tìm hiểu về việc cắt, theo như tôi thấy rằng nó có thể bị hỏng bằng cách sử dụng con trỏ đến các biến động. Nhưng làm thế nào đến? Tại sao không có cắt tại điểm đó? Tôi nghĩ bản thân mình nhưng tôi không chắc chắn. Sau khi chuyển nhượng ppet = pdog;, điểm pdog đến cùng một địa chỉ của ppet. Phải không?tìm hiểu cách sử dụng chức năng ảo và cách sử dụng con trỏ

//Program to illustrate use of a virtual function 
//to defeat the slicing problem. 

#include <string> 
#include <iostream> 
using namespace std; 

class Pet 
{ 
public: 
    virtual void print(); 
    string name;  
}; 

class Dog : public Pet 
{  
public: 
    virtual void print();//Keyword virtual not needed, but put 
         //here for clarity. (It is also good style!) 

string breed; 
}; 

int main() 
{ 
    Dog vdog; 
    Pet vpet; 

    vdog.name = "Tiny"; 
    vdog.breed = "Great Dane"; 
    vpet = vdog; 

    //vpet.breed; is illegal since class Pet has no member named breed 

    Dog *pdog; 
    pdog = new Dog; 
    pdog->name = "Tiny"; 
    pdog->breed = "Great Dane"; 

    Pet *ppet; 
    ppet = pdog; 
    ppet->print(); // These two print the same output: 
    pdog->print(); // name: Tiny breed: Great Dane 

    //The following, which accesses member variables directly 
    //rather than via virtual functions, would produce an error: 
    //cout << "name: " << ppet->name << " breed: " 
    //  << ppet->breed << endl; 
    //generates an error message: 'class Pet' has no member 
    //named 'breed' . 
    //See Pitfall section "Not Using Virtual Member Functions" 
    //for more discussion on this. 

    return 0; 
} 

void Dog::print() 
{ 
    cout << "name: " << name << endl; 
    cout << "breed: " << breed << endl; 
} 

void Pet::print() 

{ 
    cout << "name: " << endl;//Note no breed mentioned 
} 

Output:

The slicing problem: 
name: Tiny 
Note that it was print from Pet that was invoked. 
The slicing problem defeated: 
name: Tiny 
breed: Great Dane 
name: Tiny 
breed: Great Dane 
+1

[OT]: từ khóa 'ghi đè' thậm chí còn tốt hơn viết 'ảo' không cần thiết vì nó kiểm tra xem nó có thực sự là ghi đè hay không. – Jarod42

+1

Tôi chưa bao giờ nghe nói ghi đè là từ khóa. Bạn có thể giải thích một chút? @ Jarod42 – askque

+0

http://stackoverflow.com/questions/13880205/override-in-c11 – user007

Trả lời

3

lớp Derived cơ bản "bắt đầu" với một thể hiện của lớp cơ sở của họ, tiếp theo là bất kỳ trường bổ sung lớp được thừa kế bổ sung thêm. Vì vậy:

class Base { 
    int a, b; 
}; 

class Derived { 
    int c, d; 
}; 

Một ví dụ Derived trông như thế này trong bộ nhớ:

[a] [b]|[c] [d] 

Nếu bạn ngay bây giờ "lát" nó vào một trường hợp Base, điều này xảy ra:

[a] [b]|nothing 

Con trỏ tới đối tượng mặt khác luôn có cùng kích thước bất kể loại, vì vậy một con trỏ đến cơ sở có thể trỏ đến một đối tượng có nguồn gốc và không mất bất kỳ thông tin nào. Đầu của phần Base của đối tượng Derived chính xác giống với địa chỉ Derived đối tượng.

0

Khi bạn xác định một lớp, các thành viên của nó xác định bố cục bộ nhớ của nó. Các thành viên lớp dữ liệu được lưu trữ tuần tự trong bộ nhớ.

Khi bạn lấy được các lớp và kế thừa được sử dụng, các thành viên dữ liệu của lớp dẫn xuất được thêm vào đơn giản sau lớp cơ sở.

Vì vậy, khi slice xảy ra, bạn chỉ thấy "hiệu quả" các thành viên cấp cơ sở.

Bây giờ, về câu hỏi "Tại sao con trỏ oto lớp cơ sở không cắt đối tượng của lớp dẫn xuất"?

Một trong những khía cạnh quan trọng nhất của thừa kế không phải là nó cung cấp các chức năng thành viên cho các lớp có nguồn gốc, nhưng mà nó cung cấp một mối quan hệ bày tỏ giữa các lớp được thừa kế và các lớp cơ sở. Lớp dẫn xuất có thể được xem là "một loại lớp cơ sở".

Để đọc thêm, hãy kiểm tra các điều khoản upcastingdowncasting.

Upcasting đang chuyển đổi tham chiếu lớp có nguồn gốc hoặc con trỏ thành lớp cơ sở. Nói cách khác, upcasting cho phép chúng ta đối xử với một kiểu dẫn xuất như thể nó là kiểu cơ sở của nó.

Để trả lời câu hỏi của bạn từ phần nhận xét, "Ghi đè là gì?

Thu được một phần chức năng cùng tên và kiểu như một hàm ảo từ một lớp cơ sở gọi của nó trọng.

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