聊城企业做网站推广,可信网站认证好处,wordpress安装新主题,潍坊网络营销数据与函数 数据与函数局部变量全局变量类的数据成员 类的静态成员静态数据成员静态函数成员 友元友元函数友元类 函数之间实现数据共享有以下几种方式#xff1a;局部变量、全局变量、类的数据成员、类的静态成员和友元。 如何共享局部变量呢#xff1f;
在主调函数和被调… 数据与函数 数据与函数局部变量全局变量类的数据成员 类的静态成员静态数据成员静态函数成员 友元友元函数友元类 函数之间实现数据共享有以下几种方式局部变量、全局变量、类的数据成员、类的静态成员和友元。 如何共享局部变量呢
在主调函数和被调函数之间通过参数传递来共享。全局变量具有文件作用域所以作用域中的各个函数都能共享全局变量。类的数据成员具有类作用域能够被类的函数成员共享。类的静态成员。友元共享。
数据与函数
在结构化程序设计中有人提出“数据结构算法程序设计”数据结构就是数据的组织算法是用函数实现的可见数据和函数很早就被看作程序设计的重点了。面向对象程序设计中这种观点应稍作一下修改“数据结构算法对象”。就是数据和函数构成了类的对象。 面向对象程序设计中数据用来描述对象的属性函数是行为用来处理数据。将数据和函数封装到一个类里类中的函数成员可以访问数据成员函数成员之间可以实现数据共享。
局部变量
局部变量其实一般就是说具有块作用域的变量。如果要在不同的块之间共享存储在局部变量中的数据只能通过参数传递来实现。这种共享只能在主调函数和被调函数之间进行。因为局部变量具有块作用域所以不同函数中的局部变量是互不可见的这也是函数之间的一种数据隐藏在结构化程序设计中这是实现数据隐藏的唯一方式。而在面向对象设计中主要靠封装来隐藏数据。
全局变量
全局变量具有文件作用域在整个作用域中除了定义了同名局部变量的块以外的地方都可以直接访问全局变量。不同的函数在不同的地方都能访问相同的全局变量这样就实现了函数之间对全局变量的共享。 使用全局变量的优缺点
优点在进行软件开发的时候使用全局变量会很方便不用那么多的传递参数。缺点在多处使用了全局变量以后就不清楚此变量在哪些函数中使用过了除非逐个查找这样就会带来一个问题如果全局变量要做一些大的改动我们就不知道它会影响到哪些函数这时就要通过大量的测试来排除全局变量变动带来的问题。 结构化程序设计中只能使用前面提到的局部变量参数传递和全局变量这两种方式共享数据。这两种方式各有利弊局部变量隐藏性好但是传递的时候会有很大的系统开销所以一般只传递少量数据大量数据通过全局变量的方式共享但这又使得程序模块间耦合严重扩展和维护都很困难。C中可以通过具有文件作用域的全局对象来实现数据和函数的共享这实际上也属于全局变量的范畴。 类的数据成员
类中封装了数据成员和函数成员。其中数据成员可以被同一个类中的所有函数成员访问这样就实现了数据的共享。但是我们又可以通过设置访问控制权限把这种共享限制到类的范围之内这样类的数据成员对外界来说是隐藏的。也就达到了共享与隐藏的辩证结合。总起来说要达成这样的效果需要把类的数据成员都设置为私有类型。
若将类的数据参数设置为私有则外部对象不能直接访问该数据对象只能通过函数接口来访问该私有变量。这样程序模块间的耦合性就大大降低提高了程序的可扩展性和可维护性能够大大提高软件开发效率。
类的静态成员
静态成员包括静态数据成员和静态函数成员。
静态数据成员
使用场景 之前讲到的类的数据成员都是一个对象一个拷贝每个对象都有自己的数据成员的值但有时候我们需要让某个类的所有对象共享某个数据成员比如我们有一个学生类CStudent其中有学号、姓名等数据成员如果我们想要对学生人数进行统计那么这个数据应该放在哪里呢放在类外的某个地方的话数据的隐藏性就不好了。可能有朋友就说了可以在类中增加一个数据成员存放学生人数但这样就有两个坏处第一该类的每个对象都将有一个这个数据成员的副本浪费内存第二学生人数可能在不同的对象中有不同的数不一致了。这个时候就需要静态数据成员了。特性 静态数据成员存放的是类的所有对象的某个共同特征的数据对于每个对象而言该数据都是相同的在内存中只存在一份。这与类的一般数据成员不同一般数据成员会在每个对象中都有一个拷贝每个拷贝的值可能都不一样。静态数据成员由类的所有对象共同维护和使用这样就实现了类的对象间的数据共享。使用 声明静态数据成员的方式与一般数据成员不同的是其前面要加static关键字比如static int x;。静态数据成员具有静态生存期。它可以通过类名或对象名访问。用类名直接访问的方式为类名::标识符。在类的声明中仅对静态数据成员进行引用性说明就是带static的声明必须在其文件作用域的其他地方进行定义性说明也可以进行初始化如果不显式初始化的话会将此静态数据成员初始化为0。
#include iostream
using namespace std;
class CStudent // 学生类的声明
{
public: CStudent(int nID) { m_nID nID; m_nCount; } // 构造函数CStudent(CStudent s); // 拷贝构造函数int GetID(){ return m_nID;}void GetCount() { cout 学生人数m_nCountendl; } // 输出静态数据成员
private: int m_nID;static int m_nCount; // 静态数据成员的引用性说明
};
CStudent::CStudent(CStudent s)
{ m_nID s.m_nID;m_nCount ;
}int CStudent::m_nCount0; // 静态数据成员的定义性说明及初始化
int main()
{CStudent A(6); // 定义对象Acout学生A,A.GetID();A.GetCount(); // 输出此时学生个数CStudent B(A); // 定义对象B并用A初始化Bcout学生B,B.GetID(); // 输出此时学生个数B.GetCount();return 0;
}若将m_nCount的属性改为public将可以通过CStudent::m_nCount直接访问。类的使用中一般情况将数据定义为私有。
静态函数成员
类的私有静态变量无法用限位符来直接调用此时就采用静态函数来解决。 静态成员函数跟静态数据成员一样也是由类的所有对象所共有由他们共同维护和使用。声明时前面也要加static关键字比如static void fun(void);。我们可以通过类名或对象名调用公有类型的静态成员函数而非静态成员函数只能由对象名调用。 静态成员函数可以访问该类的静态数据成员和其他静态成员函数如果要访问非静态数据成员则必须将对象作为参数传递进去然后通过传进去的对象名来访问。
class A
{
public:static void f(A a);
private:int x;
};
void A::f(A a)
{coutx; //对x的引用是错误的couta.x; //正确
}所以静态成员函数访问非静态成员很麻烦它一般用来访问全局变量和同一个类中的静态数据成员。
#include iostream
using namespace std;
class CStudent // 学生类的声明
{
public: CStudent(int nID) { m_nID nID; m_nCount; } // 构造函数CStudent(CStudent s); // 拷贝构造函数int GetID() { return m_nID;}static void GetCount() { cout 学生人数m_nCountendl; } // 输出静态数据成员
private: int m_nID;static int m_nCount; // 静态数据成员的引用性说明
};
CStudent::CStudent(CStudent s)
{ m_nID s.m_nID;m_nCount ;
}int CStudent::m_nCount0; // 静态数据成员的定义性说明及初始化
int main()
{CStudent A(6); // 定义对象Acout学生A,A.GetID();A.GetCount(); // 输出此时学生个数CStudent B(A); // 定义对象B并用A初始化Bcout学生B,B.GetID(); // 输出此时学生个数CStudent::GetCount(); //直接通过类名和限定符来访问静态函数return 0;
}友元
友元是一种破坏类的封装性获取类的隐藏数据的方式。 友元机制B类的成员函数直接访问A的数据成员。 class A
{
public:int Getx() { return x; }
private:int x;
};
class B
{
public:void Set(int y);
private:A a;
};//不正确用法
void B::Set(int y)
{a.x y;
}通过友元的方式某个普通函数或者类的成员函数可以访问某个类中的私有数据这样就等于在类的封装的很好的外衣上剪开了一个小洞外界可以通过这个小洞访问到一些类内部的数据。友元提供了一种不同类或对象的成员函数之间、类的成员函数与普通函数之间共享数据的机制。它破坏了类的封装性和类数据的隐藏性但是又给我们进行软件开发提供了很多方便在我们实地进行软件开发的时候可以自己在共享和封装之间平衡一下决定是否选择使用友元。原则上尽量少使用或不使用友元除非确实很大的提高了开发效率。
在一个类中声明友元的方式是用关键字friend把普通函数、其他类的成员函数或其他类声明为此类的友元用friend声明的元素就可以访问此类的私有数据。如果友元是普通函数或是类的成员函数就叫做友元函数如果友元是一个类则叫做友元类友元类的所有成员函数均为友元函数。友元的声明位置为想使用的资源的范围内。
友元函数
友元函数是在类的声明中用关键字friend修饰的普通函数或者其他类的成员函数。友元函数虽不是本类的成员函数但在它的函数体中可以访问该类对象的私有成员和保护成员。
#include iostream
#include math.h
using namespace std;
class Data //Data类声明
{
public: //外部接口Data(int xx0) { xxx; }int GetX() { return x; }friend int Add(Data a, Data b);
private: //私有数据成员int x;
};
int Add(Data a, Data b)
{return a.x b.x;
}
int main()
{Data a(1);Data b(2);int sum Add(a, b);coutThe sum is sumendl;return 0;
}在Data类中声明友元函数Add时只给出了友元函数原型友元函数Add的实现在类Data外。我们看到在Add函数体中直接通过对象名访问了Data类的私有成员x这就是友元的强大作用。我们在类外用一般方式访问x的话必须通过公共接口GetX来实现若要访问的私有成员很多或者要访问的地方很多就要多次调用函数对于我们写代码和程序运行都有效率上的损失但是用友元也有个很大的缺点就是如果私有数据x发生结构性的变化那么友元函数就要做相应的修改所有调用友元函数的地方可能也要修改这就降低了开发效率所以是否要使用友元可以自己权衡。
友元类
类也可以声明为另一个类的友元就像友元函数那样这个作为另一个类的友元的类就叫做友元类。如果一个类B是类A的友元类则类B的所有成员函数都是类A的友元函数都能访问类A的私有成员和保护成员。
class A
{...friend class B; // 将类B声明为类A的友元类...
}class A
{
public:void Display() { coutxendl;}friend class B;
private:int x;
}
class B
{
public:void Set(int i);void Display();
private:A a;
};
void B::Set(int i)
{a.xi; // 因为类B是类A的友元类所以类B的成员函数可以访问类A对象的私有成员
}
void B::Display()
{a.Display();
}友元类特性
***友元关系不能传递***如果类B是类A的友元类C又是类B的友元类C和类A如果没有声明则没有友元关系。友元关系是单向的如果类B是类A的友元类B的成员函数可以访问类A对象的私有成员和保护成员但是类A的成员函数不能访问类B对象的私有成员和保护成员。