파생 클래스가이 코드에서 보호 된 멤버 함수를 호출 할 수없는 이유는 무엇입니까?
#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
사용할 수 있고 다른 인스턴스의 보호 된 멤버는 영원히 도달 할 수 없다고 생각했습니다 .
그러나:
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
}
};
나는 C ++로 한동안 프로그래밍을 해왔 기 때문에 이것에 다소 구역질을 느낀다. 그러나이 동작에 대한 설명을 찾을 수 없었다.
편집하다:
동일하거나 다른 인스턴스인지는 중요하지 않습니다.
int main()
{
Derived d1, d2; // Two different instances
d1.somethingDerived(d2); // This compiles fine
d1.somethingDerived(d1); // This compiles fine
return 0;
}
EDIT2 :
액세스 권한과 관련하여 사용되는 클래스의 인스턴스 가 전혀 중요하지 않은 것 같습니다.
class Base
{
public:
void something(Base& b) // Another instance
{
++b.a; // But can enter private members
}
private:
int a;
};
C ++의 액세스 제어가 클래스 단위로 작동하더라도 (인스턴스 단위가 아닌) protected
액세스 지정자에는 몇 가지 특이점이 있습니다.
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.
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.
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()
violates the above requirements.
Note that in accordance with the above rules in
void Derived::somethingDerived()
{
Base *b = this;
b->somethingProtected(); // ERROR
this->somethingProtected(); // OK
}
the first call will also fail while the second one will compile, even though both are trying to access the same entity.
I believe you have some confusion on how to access base class members. It is only this way:
class Derived : public Base
void drivedMethod() {
Base::baseMethod();
}
in your example you are trying to access a protected member of another instance.
a Derived instance will have access to it's own protected members but not to another class instance protected members, this is by design.
In fact accessing the protected members of another class, from another instance members or from the main function are in fact both under public access...
http://www.cplusplus.com/doc/tutorial/inheritance/ (look for the access specifier table to see the different levels)
Both examples prove the same thing for example:
void somethingDerived(Base& b)
{
b.somethingProtected(); // This does not
here your Derived class is getting b as a parameter, so it is getting another instance of base, then because b.somethingProtected is not public it will not complie..
this will complie:
void somethingDerived()
{
Base::somethingDerived();
your second example complies fine because you are accessing a public method on another d class
> void somethingDerived(Base& b)
> {
> b.somethingProtected(); // This does not
> }
The Derived
class can only access the protected base member in Derived
objects. It cannot access the member in objects that are not (necessarily) Derived
objects. In the cases that fail, you are trying to access the member via a Base &
, and since this might refer to an object that is not Derived
, the access can't be made.
What you have done is illegal in C++. A protected member can not be accessed by an object of a class. Only member functions can access protected members. protected
members behave just like private members except while inherited by a derived class. Consider the program given below to understand the difference between private, public and protected members.
class Base
{
private:
void somethingPrivate()
{
std::cout << "sasa" << std::endl;
}
public:
void somethingPublic()
{
std::cout << "haha" << std::endl;
}
protected:
void somethingProtected()
{
std::cout << "lala" << std::endl;
}
};
class Derived : public Base
{
public:
void somethingDerived()
{
Base b;
b.somethingPublic(); // Works fine.
somethingProtected(); // This is also fine because accessed by member function.
//b.somethingProtected(); // Error. Called using object b.
//somethingPrivate(); // Error. The function is not inherited by Derived.
}
};
'program tip' 카테고리의 다른 글
app.xaml에서 기본 WPF 창 스타일을 설정하는 방법은 무엇입니까? (0) | 2020.11.25 |
---|---|
Java는 다중 코어를 어떻게 사용합니까? (0) | 2020.11.25 |
srcdoc =“…”와 src =“data : text / html,…”의 차이점은 (0) | 2020.11.25 |
모든 공백을 무시하도록 vimdiff를 구성하는 방법이 있습니까? (0) | 2020.11.25 |
std :: pow (double, int)가 C ++ 11에서 제거 된 이유는 무엇입니까? (0) | 2020.11.25 |