为什么派生类不能在此代码中调用受保护的成员函数?
Why can't a derived class call protected member function in this code?
#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
访问说明符有一些特殊之处。
语言规范希望确保您正在访问属于派生类的某个基子对象的受保护成员。您不应该能够访问一些不相关的独立基类型对象的受保护成员。特别是,不能访问独立的基类型对象的受保护成员。只允许访问作为基子对象嵌入到派生对象中的基对象的受保护成员。
由于这个原因,您必须通过pointer->member
语法,reference.member
或object.member
语法访问受保护的成员,其中指针/引用/对象指向派生的类。这意味着在你的例子中,受保护成员somethingProtected()
不能通过Base
对象、Base *
指针或Base &
引用访问,但可以通过Derived
对象、Derived *
指针和Derived &
引用访问。您的普通somethingProtected()
访问是允许的,因为它只是this->somethingProtected()
的简写,其中this
是Derived *
类型。
b.somethingProtected()
违反了上述要求。
注意,按照上述规则在
void Derived::somethingDerived()
{
Base *b = this;
b->somethingProtected(); // ERROR
this->somethingProtected(); // OK
}
第一个调用也将失败,而第二个调用将编译,即使两者都试图访问同一个实体。
我相信您对如何访问基类成员有一些困惑。只有这样:
class Derived : public Base
void drivedMethod() {
Base::baseMethod();
}
在你的例子中,你试图访问另一个实例的受保护成员。
派生实例可以访问它自己的受保护成员,但不能访问其他类实例受保护的成员,这是设计的。
实际上访问另一个类的受保护成员,从另一个实例成员或从main函数实际上都是在公共访问下…
http://www.cplusplus.com/doc/tutorial/inheritance/(查找访问说明符表以查看不同级别)
两个例子证明了同样的事情,例如:
void somethingDerived(Base& b)
{
b.somethingProtected(); // This does not
这里你的派生类得到b作为参数,所以它得到另一个基的实例,然后因为b. somethingprotected不是公共的,它不会完成。
这将完成:
void somethingDerived()
{
Base::somethingDerived();
你的第二个例子很好,因为你正在访问另一个d类的公共方法
> void somethingDerived(Base& b)
> {
> b.somethingProtected(); // This does not
> }
Derived
类只能访问Derived
对象中受保护的基成员。它不能访问非(必须)Derived
对象中的成员。在失败的情况下,您尝试通过Base &
访问成员,并且由于这可能引用的对象不是Derived
,因此无法进行访问。
你所做的在c++中是非法的。类的对象不能访问受保护的成员。只有成员函数可以访问受保护的成员。protected
成员的行为就像私有成员一样,除了被派生类继承。考虑下面给出的程序来理解私有成员、公共成员和受保护成员之间的区别。
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.
}
};
- 在 lambda 函数 g++-4.8 中调用继承的受保护子类型
- std::异步不能调用受保护的基类方法
- 从嵌套结构调用受保护的基类函数
- C#调用C++dll试图读取或写入受保护的内存
- 尝试在 C++ 中的子类中调用父类的受保护函数
- Lua errorPANIC:调用 Lua API 时出现不受保护的错误(尝试调用 nil 值)
- 通过此指针调用受保护的基类方法,该指针投射到派生类(C++)中的基类
- C++:重写由另一个方法调用的受保护方法
- 从基类的静态模板方法中调用继承类的受保护 ctor 失败
- 在C++中为成员对象调用受保护的方法
- 受保护部分:没有匹配函数可调用
- 通过 DllImport 在 C# 中调用 C 方法 - 尝试读取或写入受保护的内存
- 在C++中调用受保护的虚拟方法
- 调用基类的受保护函数时出错
- P/在 /MT 或 /MD 上调用"受保护的内存"异常
- 无法调用继承的受保护泛型类成员
- 为什么允许在派生类中调用受保护的静态方法
- 为什么派生类不能在此代码中调用受保护的成员函数?
- 如何在仅具有受保护或私有构造函数的类上调用 ::std::make_shared
- 为什么 clang 不允许派生类调用受保护的基函数?