针对成员函数与派生类
声明:下面总结都是在先不管static
函数和变量的前提下总结的
private
- 在类成员列表前面时,
private
指定只能从类的成员函数或者友元访问这些成员
class MyClass{
private :
int data;
void func();
};
- 在基类的名称前面时,
private
指定基类的公共成员和受保护成员是派生类的私有成员
class MyClass{
};
class Drivate: public{
};
- 类中成员的默认访问是私有的。 结构或联合中成员的默认访问是公共的。
也就是说:
class myClass {
int a;
}
相当于:
class myClass {
private:
int a;
}
同样,以下代码:
struct myClass {
int a;
}
相当于:
struct myClass {
public:
int a;
}
- 基类的默认访问对于类是私有的,而对于结构是公共的
也就是说:
class Derived : Base
等效于:
class Derived : private Base
同样,以下代码:
struct Derived : Base
等效于:
struct Derived : public Base
指定私有基类时,建议显式使用 private 关键字,以便派生类的用户理解成员访问权限。
- 联合不能具有基类
看个例子:
// keyword_private.cpp
class BaseClass {
public:
// privMem accessible from member function
int pubFunc() {
return privMem; }
private:
void privMem;
};
class DerivedClass : public BaseClass {
public:
void usePrivate( int i )
{
privMem = i; } // C2248: privMem not accessible
// from derived class
};
class DerivedClass2 : private BaseClass {
public:
// pubFunc() accessible from derived class
int usePublic() {
return pubFunc(); }
};
int main() {
BaseClass aBase;
DerivedClass aDerived;
DerivedClass2 aDerived2;
aBase.privMem = 1; // C2248: privMem not accessible
aDerived.privMem = 1; // C2248: privMem not accessible
// in derived class
aDerived2.pubFunc(); // C2247: pubFunc() is private in
// derived class
}
protected
声明为protect的类成员,只能由以下项使用
- 该类的成员函数
- 该类的友元函数
- 使用公共或者受保护访问(派生自该类)的派生类
- 对受保护成员具有专用访问权限的以私有方式派生的类
在基类的名称前面时, protected 关键字指定基类的公共成员和受保护成员都是其派生类的受保护成员。
#include <iostream>
using namespace std;
class X {
public:
void setProtMemb( int i ) {
m_protMemb = i; }
void Display() {
cout << m_protMemb << endl; }
protected:
int m_protMemb;
void Protfunc() {
cout << "\nAccess allowed\n"; }
} x;
class Y : public X {
public:
void useProtfunc() {
Protfunc(); }
} y;
int main() {
// x.m_protMemb; error, m_protMemb is protected
x.setProtMemb( 0 ); // OK, uses public access function
x.Display();
y.setProtMemb( 5 ); // OK, uses public access function
y.Display();
// x.Protfunc(); error, Protfunc() is protected
y.useProtfunc(); // OK, uses public access function
// in derived class
}
public
- 在类成员列表之前, public 关键字指定可以从任何函数访问这些成员
- 在基类的名称前面时, public 关键字指定基类的公共成员和受保护成员分别是派生类的公共和受保护成员。
- 类中成员的默认访问是私有的。 结构或联合中成员的默认访问是公共的。
- 基类的默认访问对于类是私有的,而对于结构是公共的。 联合不能具有基类。
class BaseClass {
public:
int pubFunc() {
return 0; }
};
class DerivedClass : public BaseClass {
};
int main() {
BaseClass aBase;
DerivedClass aDerived;
aBase.pubFunc(); // pubFunc() is accessible
// from any function
aDerived.pubFunc(); // pubFunc() is still public in
// derived class
}
总结
对成员函数
访问类型 | 含义 |
---|---|
private |
只能由类的成员函数、友元(类或函数)使用 |
protected |
由类的成员函数、友元(类或函数)、该类的派生类使用 |
public |
任何函数都可以使用 |
综上所诉:取交集
注:访问控制同样适用于所有名称:成员函数、成员数据、嵌套类和枚举数。
对派生类
两个因素控制基类的哪些成员可在派生类中访问;这些相同的因素控制对派生类中的继承成员的访问
- 派生类是否使用
public
访问说明符声明基类 - 基类中对成员的访问权限如何
下表显示了这些因素之间的交互以及如何确定基类成员访问。
基类中的成员访问
private |
protected |
public |
---|---|---|
无论派生访问权限如何,始终不可访问 | 如果使用私有派生,则在派生类中为私有 | 如果使用私有派生,则在派生类中为私有 |
如果使用受保护派生,则在派生类中为受保护 | 如果使用受保护派生,则在派生类中为受保护 | |
如果使用公有派生,则在派生类中为受保护 | 如果使用公有派生,则在派生类中为公有 |
// access_specifiers_for_base_classes.cpp
class BaseClass
{
public:
int PublicFunc(); // Declare a public member.
protected:
int ProtectedFunc(); // Declare a protected member.
private: // 任何派生类都无法访问它。
int PrivateFunc(); // Declare a private member.
};
// Declare two classes derived from BaseClass.
class DerivedClass1 : public BaseClass
{
void foo()
{
PublicFunc();
ProtectedFunc();
PrivateFunc(); // function is inaccessible
}
};
class DerivedClass2 : private BaseClass
{
void foo()
{
PublicFunc();
ProtectedFunc();
PrivateFunc(); // function is inaccessible
}
};
int main()
{
DerivedClass1 derived_class1;
DerivedClass2 derived_class2;
derived_class1.PublicFunc();
derived_class2.PublicFunc(); // function is inaccessible
}
在 DerivedClass1 中,成员函数 PublicFunc 是公共成员,ProtectedFunc 是受保护成员,因为 BaseClass 是公共基类。 PrivateFunc 对于 BaseClass 是私有的,因此任何派生类都无法访问它。
在 DerivedClass2 中,函数 PublicFunc 和 ProtectedFunc 被视为私有成员,因为 BaseClass 是私有基类。 同样,PrivateFunc 对于 BaseClass 是私有的,因此任何派生类都无法访问它。
请注意,声明为具有私有访问权限的成员无法访问函数或派生类,除非这些函数或类是使用 friend 基类中的声明声明的。
针对静态成员
在基类指定为private
,它只会影响非静态成员。在派生类中,公共静态成员仍是可以访问的。但是,使用指针、引用或者对象访问基类的成员需要转换,此时将再次应用访问控制