我认为我知道可访问性,但是不确定我是否非常清楚地了解可见性
例如:
class X
{
int x;
};
此处,“ x”仅在班级中可见,但在班级外可访问。如果我是正确的话,有人可以解释该answer中有关如何不控制可见性的文字吗??
(C ++ 03 / 11.0)应该注意的是,对成员和基类的访问是受控的,而不是可见性。成员的名字仍然可见和隐式转换为基类仍然当这些成员和基类无法访问时,请考虑。的建立给定结构的解释时不考虑访问控制。如果建立的解释是利用无法访问的成员名称或基类,其构造为格式不正确。
也许这个例子有帮助:
class Bob
{
private:
int foo(int, int);
};
class David : Bob
{
void goo() {
int a = foo(1, 2); // #1
}
};
class Dani : Bob
{
void foo();
void goo() {
int a = foo(1, 2); // #2
}
};
在第1行上,名称foo
为可见,但其命名的功能不是可访问(由于对Bob
私有)。这是一个编译错误,但是编译器知道存在一个可能会匹配但无法访问的潜在函数Bob::foo
。
在第2行上,名称foo
仅指Dani::foo
,而Bob::foo
是不可见(因为它是隐藏),因此根本没有匹配函数呼叫foo(1, 2)
。这也是一个编译错误,但是这次错误是该调用根本没有匹配函数。
C ++具有一些有关私有类成员名称可见性和可访问性的深奥功能。根据定义,班级成员和朋友只能访问私有班级成员名称。但是,可见性规则会使许多人困惑。它们可以总结如下。
在当今的C ++(“ C ++ 03”和更早的版本)中,可访问性和可见性的概念是独立。每当类和名称空间的成员位于“范围”,从声明的角度来看,没有机制可以降低这种可见性。可访问性只是类成员的一个参数,并且与能见度。对于新手C ++程序员来说,后一种观察常常令人惊讶。参见此PDF。
请考虑以下示例。
#include < complex>
class Calc
{
public:
double Twice( double d );
private:
int Twice( int i );
std::complex Twice( std::complex c );
};
int main()
{
Calc c;
return c.Twice( 21 ); // error, Twice is inaccessible
}
[当编译器必须解决对函数的调用时,它将按顺序执行三项主要工作:
在进行其他操作之前,编译器会搜索一个范围至少有一个名为Twice的实体,并列出了候选人列表。在这种情况下,名称查找首先会在Calc范围内进行查找,以查看是否至少有一个名为Twice的函数;如果没有,根据类和封闭的名称空间将被依次考虑,时间,直到找到至少有一个候选范围。在这但是,在这种情况下,编译器查找的第一个作用域已经具有一个名为Twice的实体-实际上,它拥有三个实体,因此三人组成为候选人。 (有关名称的更多信息C ++中的查找,并讨论了它如何影响您的方式应该打包您的类及其接口]]
接下来,编译器执行重载解析以选择唯一的最匹配的候选人。在这种情况下,是21,这是一个整数,可用的重载取一倍,int,并且很复杂。显然,int参数最适合int参数(完全匹配,没有任何转换),然后选择了两次(int)。
最后,编译器执行可访问性检查以确定是否可以调用所选函数。
请注意,accessibility
作为示例,静态成员在整个应用程序运行过程中都是visible
,但仅对应用于它们的修饰符是accessible。注意:当声明一个class
时,作用域默认为私有(与struct
相对,成员默认情况下为公共。)
可访问性和可见性是独立的,尤其在这种情况下会造成混淆: