原址:http://wenku.baidu.com/view/4e13d5343968011ca300912c.html
(注释: 为了尊重原作者,在不改变内容的前提下,我进行了格式和内容的编辑,增强阅读体验。这位兄弟的文章,挺全面的,不过也有一点啰嗦。好像这个文章的上传作者也在杭州工作,有机会联系下,一起讨论交流下C++的一些知识。)
关于类成员函数中访问同类对象的私有成员,主要包含以下几种场景:
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;
};
4).
#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;
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属性不发生改变;
如下所示:
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;
}
};
编译出错;
若将fb成员函数改为 :
void fb(B &a)
{
cout<<a.a<<endl;
}
则编译运行都没问题:
保护类型只能被本类中的方法或者派生类访问,不能被本类的具体对象访问。
a是类A的保护类型成员,能被A中的方法(函数)访问,能被B类访问,不能被类A的具体对象访问。
一个类的保护成员或私有成员只能被该类的成员函数或该类的友元函数来访问,外部代码不能访问。
B类中的函数fb,对于A类中的保护成员变量a,是外部代码不能通过该类的对象直接访问。
由于B类公有继承了A类,a在A类中是保护成员,则在B类中也是保护成员,因此B类中的函数可以访问自己的保护成员。
分享到:
相关推荐
面向对象程序设计C++详细实验报告 含代码,结果 实验要求: (1) 将数据成员改为私有的; (2) 将输入和输出的功能改为由成员函数实现; (3) 在类体内声明成员函数,而在类外定义成员函数。
可以直接用赋值的方式来修改,但易语言只有私有成员,无法直接用赋值的方式来改动私有成员的数据值,这个例程演示了如何把内部私有成员的数据地址跟外部变量的变量地址打通,从而间接实现从类外部修改内部私有成员的...
题目:建立一个名为Student的类,该类有以下几个私有成员变量:学生姓名、学号、性别、年龄。还有以下两个成员函数:一个用于初始化学生姓名、学号、性别和年龄的构造函数,一个用于输出学生信息的函数。编写一个...
Java反射机制,万物皆对象,class也是一个类的对象,通过类类型,反射获得类的成员属性,构造方法,成员方法,并调用类中的方法,也可以调用私有方法。
易语言从外部访问类的私有成员源码,从外部访问类的私有成员,私有成员外部初始化,测试_输出私有成员的值,子程序_说明,取变量数据地址_ASM,变量_ASM变量地址还原数据指针,变量_ASM变量地址指向新数据地址
通过引入了Class对象,可以创建拥有私有函数,私有属性,函数实现对外不可见的能力,私有属性以及私有函数只有内部才可以调用
C++ 将构造函数和析构函数声明为私有函数的原因
C#net反射实现访问类中的私有变量或者方法
易语言从外部访问易语言类的私有成员源码.rar 易语言从外部访问易语言类的私有成员源码.rar 易语言从外部访问易语言类的私有成员源码.rar 易语言从外部访问易语言类的私有成员源码.rar 易语言从外部访问易语言类...
声明一个时间类,时间类中有3个私有数据成员(Hour, Minute, Second)和两个公有成员函数(SetTime和Print_Time)。SetTime根据传递的3个参数为对象设置时间;Print_Time负责将对象表示的时间显示输出.
利用自定义数据可以把单个的私有成员打包,然后将外部变量的地址指向类内部的私有成员数据地址,就可以实现修改外部变量的同时,类内部的私有成员数据也发生了变化。从而实现了类内部私有成员的数据可以直接操作的...
一般地,线程要读写类的私有成员变量,只有两种方法:将全局函数声明为类友元friend,或者使用静态的成员函数static。那非静态的成员函数呢?一般地方都说的是,不行,做不了。。。为什么不行?都是代码区的代码,...
编写Student类,类中包含学生姓名,学号等私有数据成员。 使用JAVA反射机制修改一个学生对象的私有数据成员(不允许调用setters)
1 、定义一个时间类Time,有三个私有成员变量Hour、Minute、Second,定义构造函数、析构函数以及用于改变、获取、输出时间信息的公有函数,主函数中定义时间对象,并通过调用各种成员函数完成时间的设定、改变、获取...
1 、定义一个时间类Time,有三个私有成员变量Hour、Minute、Second,定义构造函数、析构函数以及用于改变、获取、输出时间信息的公有函数,主函数中定义时间对象,并通过调用各种成员函数完成时间的设定、改变、获取...
外部访问类的私有成员+修改虚表 这种操作说明了C++的无所不能
只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,特别是...
本程序是使用友元成员函数的一个典型例子,简单、实用,对于初学者很有帮助。
易语言源码从外部访问易语言类的私有成员源码.rar 易语言源码从外部访问易语言类的私有成员源码.rar 易语言源码从外部访问易语言类的私有成员源码.rar 易语言源码从外部访问易语言类的私有成员源码.rar 易语言...
1、类中声明的私有变量 都有谁可以访问?“私有”是对谁而言的?是类本身还是类的实例? msdn 中说: private Class members declared as private can be used only by member functions and friends (classes or ...