問題描述
#include <iostream>
class Base
{
protected:
void somethingProtected()
{
std::cout << "lala" << std::endl;
}
};
class Derived : public Base
{
public:
void somethingDerived()
{
Base b;
b.somethingProtected(); // This does not compile
somethingProtected(); // But this is fine
}
};
int main()
{
Derived d;
d.somethingDerived();
return 0;
}
我想也許只有this
的受保護成員可以使用,而其他實例的受保護成員永遠無法訪問.
I thought that maybe only the protected members of this
can be used and protected members of other instances are forever unreachable.
但是:
class Derived : public Base
{
public:
void somethingDerived(Derived& d)
{
d.somethingProtected(); // This compiles even though d is
// potentially a different instance
}
void somethingDerived(Base& b)
{
b.somethingProtected(); // This does not
}
};
我對此感到有點惡心,因為我已經(jīng)用 C++ 編程了一段時間,但我找不到對這種行為的任何解釋.
I feel kind of nauseated by this, since I have been programming in C++ for some time, but I could not find any explanation for this behaviour.
無論是相同的還是不同的實例都沒有關(guān)系:
It doesn't matter if it is the same or a different instance:
int main()
{
Derived d1, d2; // Two different instances
d1.somethingDerived(d2); // This compiles fine
d1.somethingDerived(d1); // This compiles fine
return 0;
}
編輯 2:
似乎在訪問權(quán)限方面,使用類的什么實例根本無關(guān)緊要:
It seems that when it comes to access rights, it doesn't matter at all what instance of a class is being used:
class Base
{
public:
void something(Base& b) // Another instance
{
++b.a; // But can enter private members
}
private:
int a;
};
推薦答案
盡管 C++ 中的訪問控制是基于每個類(而不是基于每個實例)的,protected
訪問說明符具有一些特點.
Even though access control in C++ works on per-class basis (as opposed to per-instance basis), protected
access specifier has some peculiarities.
語言規(guī)范希望確保您正在訪問屬于派生類的某個基本子對象的受保護成員.您不應(yīng)該能夠訪問一些基本類型的不相關(guān)的獨立對象的受保護成員.特別是,您不能訪問基本類型的 freestanding 對象的受保護成員.您只能訪問作為基礎(chǔ)子對象嵌入到派生對象中的基礎(chǔ)對象的受保護成員.
The language specification wants to ensure that you are accessing a protected member of some base subobject that belongs to the derived class. You are not supposed to be able access protected members of some unrelated independent objects of base type. In particular, you cannot access protected members of freestanding objects of base type. You are only allowed to access protected members of base objects that are embedded into derived objects as base subobjects.
因此,您必須通過pointer->member
語法、reference.member
或object.member
語法訪問受保護的成員,其中指針/引用/對象指的是派生類.
For this reason, you have to access protected members through pointer->member
syntax, reference.member
or object.member
syntax, where the pointer/reference/object refers to the derived class.
這意味著在您的示例中,無法通過 Base
對象、Base *
指針或 訪問受保護成員
引用,但它可以通過 somethingProtected()
基礎(chǔ) &Derived
對象、Derived *
指針和 Derived &
引用訪問.允許您的普通 somethingProtected()
訪問,因為它只是 this->somethingProtected()
的簡寫,其中 this
的類型為 <代碼>派生的*.
This means that in your example, protected member somethingProtected()
is not accessible through Base
objects, Base *
pointers or Base &
references, but it is accessible through Derived
objects, Derived *
pointers and Derived &
references. Your plain somethingProtected()
access is allowed, since it is just a shorthand for this->somethingProtected()
where this
is of type Derived *
.
b.somethingProtected()
違反了上述要求.
注意按照上面的規(guī)則
void Derived::somethingDerived()
{
Base *b = this;
b->somethingProtected(); // ERROR
this->somethingProtected(); // OK
}
第一個調(diào)用也會失敗,而第二個調(diào)用會編譯,即使兩者都試圖訪問同一個實體.
the first call will also fail while the second one will compile, even though both are trying to access the same entity.
這篇關(guān)于為什么派生類不能在這段代碼中調(diào)用受保護的成員函數(shù)?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!