2015-01-04 18 views
6

Tôi có một câu hỏi về đa thừa kế của chức năng được bảo vệ và đa hình. nó khá khó để mô tả nó vì vậy tôi hy vọng nó sẽ được rõ ràng, đủ.đa kế thừa được bảo vệ với đa hình

phép nói rằng tôi có ba lớp:

class baseClass 
{ 
protected: 
    virtual int function() = 0; 
}; 


class derived_A:public baseClass 
{ 
    int function() 
    { 
     //implementation 1 
    }; 
} 


class derived_B:public baseClass 
{ 
    int function() 
    { 
     //implementation 2 
    }; 
} 


class derived_C:public derived_A, public derived_B 
{ 
    baseClass ** p_arr; //array of pointers of baseClass kind (polymorphism) 
    int x=0; 

    for (int i=0; i<arraySize; i++) // array size = many classes like derived_A, derived_B... 
    { 
    x = p_arr[i]->function(); //I already have function that builds this array 
           //it is not the question so I didn't put it here. 
    // process x 
    } 

cuối cùng question- tôi làm thế nào tôi có thể truy cập "chức năng bảo vệ()" từ lớp derived_C (bên trong vòng lặp for)? Tôi hơi bối rối .. và sẽ rất vui khi được giải thích.

cảm ơn.

}

Trả lời

2

Khi C++ cho phép truy cập đến protected thành viên, nó chỉ cho các thành viên của đối tượng này (như đã đề cập herehere). Mã số x = p_arr[i]->function() cố gắng gọi một phương thức trong đối tượng khác, do đó trình biên dịch phàn nàn.

Để khắc phục mã của bạn, bạn có thể làm function công cộng, hoặc thêm một tuyên bố friend để baseClass, như thế này:

class baseClass 
{ 
public: 
    virtual int function() = 0; 
}; 

Hoặc

class baseClass 
{ 
protected: 
    friend class derived_C; 
    virtual int function() = 0; 
}; 

Tuy nhiên, để duy trì khả năng tiếp cận protected và không đề cập đến tên của lớp dẫn xuất trong lớp cơ sở, bạn có thể sửa mã của mình bằng cách thêm một hàm truy cập static vào lớp cơ sở:

class baseClass 
{ 
protected: 
    virtual int function() = 0; 
    static int call_the_function_on_object(baseClass& obj) {return obj.function();} 
}; 

Sử dụng nó (trong một lớp học có nguồn gốc) theo cách này:

x = call_the_function_on_object(*p_arr[i]); 

Bạn cũng có thể cung cấp cho các chức năng accessor cùng tên, nhưng sau đó, nếu derived_C bạn override phương thức ảo, nó sẽ ẩn accessor chức năng. Bạn có thể khắc phục điều đó bằng cách tham khảo lớp cơ sở một cách rõ ràng:

class baseClass 
{ 
protected: 
    virtual int function() = 0; 
    static int function(baseClass& obj) {return obj.function();} 
}; 

... 
class derived_C:public derived_A, public derived_B 
{ 
    ... 
     x = baseClass::function(*p_arr[i]); 
    ... 
} 
+0

cảm ơn bạn đã trả lời chi tiết của bạn! Tôi đã cố gắng bắt đầu với giải pháp đầu tiên của bạn tuyên bố hàm là bạn: tại BaseClass: friend int derived_c :: function(); nhưng tôi nhận được lỗi này: 'derived_C': không phải là tên lớp hoặc không gian tên tại sao tôi nhận được thông báo này? – user1673206

+0

cũng vậy, nếu tôi thêm #include BaseClass, nó sẽ bao gồm hình tròn và "thiết kế xấu" như tôi đã thấy trên các bài đăng khác ... hoặc có thể tôi đã sai? – user1673206

+0

Theo như tôi biết, không thể khai báo một phương thức bạn bè trong một lớp không khai báo. Vì vậy, chỉ cần làm cho toàn bộ 'derived_C' lớp một người bạn. Tôi đã thêm cú pháp để làm điều đó. – anatolyg

1

Trong trường hợp này, function() của bạn là riêng tư trong lớp học có nguồn gốc. Vì vậy, từ derived_C bạn không thể truy cập trực tiếp vào chức năng đó.

Tuy nhiên, nếu bạn sẵn sàng làm cho nó public/protected. Sau đó, bạn có thể sử dụng: -

derived_C dc; 
dc.derived_A::function(); 
dc.derived_B::function(); 
+1

'protected' sẽ đủ. –

+0

Trong ngữ cảnh của câu trả lời này, nó sẽ. Nhưng mã của OP thì khác, nên chỉ có 'public' mới có thể giúp được. – anatolyg

+0

@anatolyg Tại sao bạn nghĩ vậy? –

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