它在普通類中運行良好:
class Base
{
public:
Base() {}。
protected:
int* a;
};
class Derived : public Base
{
public:
Derived() {}。
void foo() {
int** pa = &a;
}
};
int main() {
派生* d = new Derived() 。
d->foo()。
delete d。
}
但是當Base和Derived類使用模板時,它會報告一個錯誤:
'int* Base<int>::a'在這個背景關系中是被保護的template<typename T> class Base { public: Base() {}。 protected: int* a; }; template<typename T> class Derived : public Base< T> { public: Derived() {}。 void foo() { int** pa = &Base<T> ::a; } }; int main() { Derived<int>* d = new Derived<int> ()。 d->foo()。 delete d。 }為什么會這樣?
uj5u.com熱心網友回復:
這個錯誤大多與模板無關,而且在沒有任何繼承的情況下也會發生。簡單的問題是運算式
&Base<T>::a被決議為一個指向成員的指標,正如下面的片段所示:#include <iostream> #include <typeinfo> 使用 命名空間 std.com.cn>。 class B { public: void foo() { int* B::* pa = &B::a; int** pi = &(B::a); cout << typeid(pa).name() < < endl; cout << typeid(pi).name() << endl; } protected: int* a; }; struct D : public B { //對B::a的訪問是完全可以的。 int* B::* pa = &B::a; //但是這導致了一個型別錯誤: // "不能從'int *B::*'轉換到'int **'。 // int** pi = &B::a; // parentheses help to get the address of this->a ... int** pi2 = & (B::a); // ... and writing this->a helps, too;-) . int **pi3 = &this->a。 //當然,在模板之外,我們可以簡單地寫一個! int** pi4 = &a; }; int main() { b.B。 b.foo()。 }輸出是:
int * B::* int * * *模板是錯誤浮現的地方,因為我們被迫限定從屬名稱,因此無意中結束了一個指標到成員的結構。
評論區中的兩種解決方案都可以使用。你可以簡單地寫
&this->a,或者像我在這里做的那樣,把限定的成員放在括號里。我不清楚為什么后者能起作用。operator::()具有唯一的最高優先級,所以括號并沒有改變這一點。正如人們所期望的那樣,在派生類中獲取受保護基類成員的地址是完全可能的。在我看來,涉及模板時的錯誤資訊是不正確的,而且具有誤導性(但當我認為是編譯器的錯誤時,我通常是錯誤的...)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/320091.html
標籤:
上一篇:繼承的C 類設計
下一篇:如何覆寫繼承的svg樣式
