问题(知识点)描述:
a. 在 C++的类的成员函数中,允许直接访问该类 的对象的私有成员变量。
b. 在类的成员函数中可以访问同类型实例的私有变量 。
c.拷贝构造函数里, 可以直接访问另外一个同类对象(引用) 的私有成员。
d. 类的成员函数可以直接访问作为其参数的同类型对象的私有成员。
举例描述上述知识:
1).在拷贝构造函数中可以访问引用对象的私有变量:例如:
class Point
{
public:
Point(int xx=0,int yy=0){X=xx;Y=yy;}
Point(Point &p);
private:
int X,Y;
};
Point::Point (Point &p)
{
X=p.X;
Y=p.Y;
}
2). 在类的成员函数中可以访问同类型实例的私有变量
class A
{
public:
int getA() const { return a; }
void setA(int val) { a = val; }
void assign(A& _AA)
{
this->a = _AA.a;
_ AA.a = 10; //可以直接访问
}
void display()
{
cout<<"a:"<<a<<endl;
}
private:
int a;
};
3).
#include <iostream>
using namespace std;
class TestClass
{
public:
TestClass(int amount)
{
this->_amount = amount;
}
void UsePrivateMember()
{
cout<<"amount:"<<this->_amount<<endl;
/*----------------------*/
TestClass objTc(10);
objTc._amount = 15; //访问同类型实例的私有变量
cout<<objTc._amount<<endl;
/*----------------------*/
}
private:
int _amount;
};
int main()
{
TestClass tc(5);
tc.UsePrivateMember();
return(0);
}
关于该问题(知识点)的讨论和或解释:
1. 私有是为了实现“对外”的信息隐藏,或者说保护,在类自己内部,有必要禁止私有变量
的直接访问吗?难道还要让我们声明一个类为自身的友元?
Point::Point(Point &p)
{
X=p.X; //这在 Point 类中的 Point 函数内,所以没错。
Y=p.Y;
}
请记住你是在定义你的类,不是在用。
2. C++的访问修饰符的作用是以类为单位,而不是以对象为单位 。
通俗的讲,同类的对象间可以“互相访问”对方的数据成员,只不过访问途径不是直接访
问.
步骤是:通过一个对象调用其 public 成员函数,此成员函数可以访问到自己的或者同类其他对
象的 public/private/protected 数据成员和成员函数(类的所有对象共用),而且还需要指明是
哪个对象的数据成员(调用函数的对象自己的成员不用指明 , 因为有 this 指针; 其他对象的数据
成员可以通过引用或指针间接指明)
可以提供访问行为的主语为“函数”。
类体内的访问没有访问限制一说, 即 private 函数可以访问 public/protected/private 成
员函数或数据成员,同理,protected 函数,public 函数也可以任意访问该类体中定义的成员
public 继承下,基类中的 public 和 protected 成员继承为该子类的 public 和 protected 成员
(成员函数或数据成员),然后访问仍然按类内的无限制访问 。
3. 注意公有和私有的概念:每个类的对象都有自己的存贮空间, 用于存储内部变量和类成员;
但同一个类的所有对象共享一组类方法,即每种方法只有一个源本。很明显,类方法是所
有该类对象共同使用的,因此不存在每个对象有一组类方法的副本。源本的类方法自然可
以访问所有该类对象的私有成员。
4. 访问权限是相对于类而言,而非对象!
一个问题, 为什么成员函数可以访问私有成员呢?结果很显然, 如果不能访问, 那么私有成员的
存在就没有了意义。 而对于成员函数中允许访问对象的数据成员 , 一方面保证了安全性与封装性,
另一方面提供方便的操作。 第一句话的解释, 就是承认只有成员函数可以访问私有成员, 这里不
涉及友元及派生。 这样一来, 安全性仍然得到了保证, 也完成了封装工作。 对于第二句话, 试想,
如果都得靠接口来实现数据传送, 那么操作是否极为不便?既然处于成员函数中, 已经保证了足
够的安全和封装性, 那么这里如果还得借助接口, 就有些不合情合理了。 作为对数据成员的灵活
处理, 设计者允许在成员函数中访问对象的私有成员 , 为使用者提供了很大的方便。 这同时也反
映了语言的灵活性和原则性.
C++中类访问权限控制:
第一:private, public, protected 访问标号的访问范围,在没有继承的情况下:
private:
只能由 1.该类中的函数、2.其友元函数访问。
不能被任何其他访问,该类的对象也不能访问。
protected:
可以被 1.该类中的函数、2.子类的函数、以及 3.其友元函数访问。
但不能被该类的对象访问。
public :
可以被 1.该类中的函数、2.子类的函数、3.其友元函数访问,也可以由 4.该类的对象访问。
注:友元函数包括 3 种:设为友元的普通的非成员函数;设为友元的其他类的成员函数;设为
友元类中的所有成员函数。
第二:类的继承后方法属性变化,具体情况如下:
private 属性是不能够被继承的,protected 继承和 private 继承能降低访问权限。
使用 private 继承,父类的 protected 和 public 属性在子类中变为 private;
使用 protected 继承,父类的 protected 和 public 属性在子类中变为 protected;
使用 public 继承,父类中的 protected 和 public 属性不发生改变;
如下所示:
public: protected: private:
public 继承 public protected 不可用
protected 继承 protected protected 不可用
private 继承 private private 不可用
class A
{
public:
A(int i) : a(i){}
protected:
int a;
};
class B : public A
{
public:
B(int i) : A(i) {}
void fb(A &a) {cout<<a.a<<endl;}
};
编译出错;若将倒数第二行改为
void fb(B &a) {cout<<a.a<<endl;}
则编译运行都没问题:
保护类型只能被本类中的方法或者派生类访问,不能被本类的具体对象访问。 a
是类 A 的保护类型成员,能被 A 中的方法(函数)访问,能被 B 类访问,不能被类
A 的具体对象 A a 访问。
一个类的保护成员或私有成员只能被该类的成员函数或该类的友元函数来访
问,外部代码不能访问,B 类中的函数 fb 对于 A 类中的保护成员变量 a 来说是外部
代码不能通过该类的对象直接访问,由于 B 类公有继承了 A 类,a 在 A 类中是保护
成员,则在 B 类中也是保护成员,因此 B 类中的函数可以访问自己的保护成员。
a. 在 C++的类的成员函数中,允许直接访问该类 的对象的私有成员变量。
b. 在类的成员函数中可以访问同类型实例的私有变量 。
c.拷贝构造函数里, 可以直接访问另外一个同类对象(引用) 的私有成员。
d. 类的成员函数可以直接访问作为其参数的同类型对象的私有成员。
举例描述上述知识:
1).在拷贝构造函数中可以访问引用对象的私有变量:例如:
class Point
{
public:
Point(int xx=0,int yy=0){X=xx;Y=yy;}
Point(Point &p);
private:
int X,Y;
};
Point::Point (Point &p)
{
X=p.X;
Y=p.Y;
}
2). 在类的成员函数中可以访问同类型实例的私有变量
class A
{
public:
int getA() const { return a; }
void setA(int val) { a = val; }
void assign(A& _AA)
{
this->a = _AA.a;
_ AA.a = 10; //可以直接访问
}
void display()
{
cout<<"a:"<<a<<endl;
}
private:
int a;
};
3).
#include <iostream>
using namespace std;
class TestClass
{
public:
TestClass(int amount)
{
this->_amount = amount;
}
void UsePrivateMember()
{
cout<<"amount:"<<this->_amount<<endl;
/*----------------------*/
TestClass objTc(10);
objTc._amount = 15; //访问同类型实例的私有变量
cout<<objTc._amount<<endl;
/*----------------------*/
}
private:
int _amount;
};
int main()
{
TestClass tc(5);
tc.UsePrivateMember();
return(0);
}
关于该问题(知识点)的讨论和或解释:
1. 私有是为了实现“对外”的信息隐藏,或者说保护,在类自己内部,有必要禁止私有变量
的直接访问吗?难道还要让我们声明一个类为自身的友元?
Point::Point(Point &p)
{
X=p.X; //这在 Point 类中的 Point 函数内,所以没错。
Y=p.Y;
}
请记住你是在定义你的类,不是在用。
2. C++的访问修饰符的作用是以类为单位,而不是以对象为单位 。
通俗的讲,同类的对象间可以“互相访问”对方的数据成员,只不过访问途径不是直接访
问.
步骤是:通过一个对象调用其 public 成员函数,此成员函数可以访问到自己的或者同类其他对
象的 public/private/protected 数据成员和成员函数(类的所有对象共用),而且还需要指明是
哪个对象的数据成员(调用函数的对象自己的成员不用指明 , 因为有 this 指针; 其他对象的数据
成员可以通过引用或指针间接指明)
可以提供访问行为的主语为“函数”。
类体内的访问没有访问限制一说, 即 private 函数可以访问 public/protected/private 成
员函数或数据成员,同理,protected 函数,public 函数也可以任意访问该类体中定义的成员
public 继承下,基类中的 public 和 protected 成员继承为该子类的 public 和 protected 成员
(成员函数或数据成员),然后访问仍然按类内的无限制访问 。
3. 注意公有和私有的概念:每个类的对象都有自己的存贮空间, 用于存储内部变量和类成员;
但同一个类的所有对象共享一组类方法,即每种方法只有一个源本。很明显,类方法是所
有该类对象共同使用的,因此不存在每个对象有一组类方法的副本。源本的类方法自然可
以访问所有该类对象的私有成员。
4. 访问权限是相对于类而言,而非对象!
一个问题, 为什么成员函数可以访问私有成员呢?结果很显然, 如果不能访问, 那么私有成员的
存在就没有了意义。 而对于成员函数中允许访问对象的数据成员 , 一方面保证了安全性与封装性,
另一方面提供方便的操作。 第一句话的解释, 就是承认只有成员函数可以访问私有成员, 这里不
涉及友元及派生。 这样一来, 安全性仍然得到了保证, 也完成了封装工作。 对于第二句话, 试想,
如果都得靠接口来实现数据传送, 那么操作是否极为不便?既然处于成员函数中, 已经保证了足
够的安全和封装性, 那么这里如果还得借助接口, 就有些不合情合理了。 作为对数据成员的灵活
处理, 设计者允许在成员函数中访问对象的私有成员 , 为使用者提供了很大的方便。 这同时也反
映了语言的灵活性和原则性.
C++中类访问权限控制:
第一:private, public, protected 访问标号的访问范围,在没有继承的情况下:
private:
只能由 1.该类中的函数、2.其友元函数访问。
不能被任何其他访问,该类的对象也不能访问。
protected:
可以被 1.该类中的函数、2.子类的函数、以及 3.其友元函数访问。
但不能被该类的对象访问。
public :
可以被 1.该类中的函数、2.子类的函数、3.其友元函数访问,也可以由 4.该类的对象访问。
注:友元函数包括 3 种:设为友元的普通的非成员函数;设为友元的其他类的成员函数;设为
友元类中的所有成员函数。
第二:类的继承后方法属性变化,具体情况如下:
private 属性是不能够被继承的,protected 继承和 private 继承能降低访问权限。
使用 private 继承,父类的 protected 和 public 属性在子类中变为 private;
使用 protected 继承,父类的 protected 和 public 属性在子类中变为 protected;
使用 public 继承,父类中的 protected 和 public 属性不发生改变;
如下所示:
public: protected: private:
public 继承 public protected 不可用
protected 继承 protected protected 不可用
private 继承 private private 不可用
class A
{
public:
A(int i) : a(i){}
protected:
int a;
};
class B : public A
{
public:
B(int i) : A(i) {}
void fb(A &a) {cout<<a.a<<endl;}
};
编译出错;若将倒数第二行改为
void fb(B &a) {cout<<a.a<<endl;}
则编译运行都没问题:
保护类型只能被本类中的方法或者派生类访问,不能被本类的具体对象访问。 a
是类 A 的保护类型成员,能被 A 中的方法(函数)访问,能被 B 类访问,不能被类
A 的具体对象 A a 访问。
一个类的保护成员或私有成员只能被该类的成员函数或该类的友元函数来访
问,外部代码不能访问,B 类中的函数 fb 对于 A 类中的保护成员变量 a 来说是外部
代码不能通过该类的对象直接访问,由于 B 类公有继承了 A 类,a 在 A 类中是保护
成员,则在 B 类中也是保护成员,因此 B 类中的函数可以访问自己的保护成员。