[英]Is this a standard C++ code?
下面簡單的一段代碼,用VC2008編譯但g ++拒絕代碼:
#include <iostream>
class myclass
{
protected:
void print() { std::cout << "myclass::print();"; }
};
struct access : private myclass
{
static void access_print(myclass& object)
{
// g++ and Comeau reject this line but not VC++
void (myclass::*function) () = &myclass::print;
(object.*function)();
}
};
int main()
{
myclass object;
access::access_print(object);
}
(/W4)
在VC中打開,但它沒有發出任何警告。
g ++ 4.4.1給出了一個錯誤:
correct.cpp: In static member function ‘static void access::access_print(myclass&)’:
correct.cpp:6: error: ‘void myclass::print()’ is protected
如果g ++是正確的,我如何訪問類的受保護成員? 有另一種方式嗎?
@Suroot你是說我不應該傳遞myclass
類型的對象? 實際上並不重要,g ++給出了相同的錯誤,但VC編譯代碼時沒有任何警告。
#include <iostream>
class myclass
{
protected:
void print() { std::cout << "myclass::print();"; }
};
struct access : private myclass
{
static void access_print()
{
myclass object;
void (myclass::*function) () = &myclass::print;
(object.*function)();
}
};
int main()
{
access::access_print();
}
這是對的。 上面引用了標准的相關部分,但這是它的價值的基本原理。
C ++中protected
的語義意味着“這個成員可以從這個類或任何派生類的方法訪問,但只有當被訪問的對象的動態類型保證與 *this
的類型相同或派生時 ” 。
后一點可能不太明顯,所以這是一個例子:
class Base {
protected:
int X;
};
class Derived : public Base {
void Foo(Base* b, Derived* d) {
this->X = 123; // okay - `this` is definitely either Derived
// or inherited from Derived
d->X = 456; // also okay, for the same reason
b->X = 789; // NOT OKAY; b could point to instance of some other class
// Derived2, which isn't inherited from Derived!
}
};
這是設計 - 想法是Derived2
可以對如何處理受保護的成員(不變量等等)有自己的看法,它應該嚴格地介於它和它的基類(及其派生類之間,但是只有當它決定不通過使隱藏的那場private
)。 跨層次訪問與此模型相反,因為它實際上意味着基類預先決定整個層次結構; 對於深度層次結構之上的非常抽象的類,這可能是不合需要的。
現在回到你的具體問題 - 現在應該是相當明顯的。 獲得成員函數指針后,可以使用匹配類型的任何接收器調用該指針指向的函數。 對於基類的受保護方法,這意味着,如果你可以獲得一個指向它的指針到基類(而不是你自己的類),你可以調用它,向它傳遞一個指向不同於你的類型的指針類(或從中派生),違反了上面概述的受保護訪問規則。 因此,您不得這樣做。
我相信g ++和comeau是正確的。 受保護成員的說明符必須是“access”或派生類型,所以我相信代碼:
void (myclass::*function) () = &access::print;
會編譯。
我相信這是因為11.5.1:
...如果訪問[編輯。 對於受保護的成員]是形成指向成員的指針,嵌套名稱說明符應命名派生類(或從該類派生的任何類)。
由於object是作為參數傳遞的,因此您無法直接訪問private / protected函數。
編輯:將myclass更改為object
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.