`

《C++学习笔记》【封装性】对象及其内存存储内容

    博客分类:
  • C++
阅读更多
===============================================
转载时请表明出处:http://www.cofftech.com/thread-1389-1-1.html
===============================================
面向对象的方法以对象为中心和出发点。对象可以是某一类概念实体的实例,也可以是现实生活中的一个物理实体。
    在上一节的类class integ的定义中,数据成员int j(一般情况下一个类可有多个数据成员)可以具有不同数值或不同数值的组合,可以使用各种成员函数对它进行不同操作。这种情况下,只用一个类来表达是不够的。应该为该类建立不同对象来加以表达;正如对于整型数据需要建立不同整型变量那样。例如:
int  j, k, m;       
其中j、k和m是不同整型变量,它们是整型数据类型int的不同实例;而
integ  obj1, obj2, obj3; 中的obj1、obj2和obj3则是class integ的不同对象,它们是class integ的不同实例,它们的数据成员具有不同数值组合。
此处,类是一种用户自定义的数据类型,而对象是一个类的实例。正如j、k和m是整型类(int)数据的实例一样。
建立对象的过程是类实例化(instantiation of classes)的过程。
建立对象有两种方法:
1.      定义类的同时建立对象:
class integ  {
  int j;
public:
  integ( ) { j = 6; }                       //构造函数
  int  sq();
  int  read();
} obj;
此处在定义class integ的同时也建立对象obj。
此法的缺点是所建立的对象是全局对象,从软件工程的观点看是不合适的。因此以下法为宜。
2.      常用的方法:先定义类然后再建立对象:
例如在主函数外定义或说明一个类,然后在主函数内建立对象,即:
void main( )
{
       integ  obj;
       ……
}

“封装性”的[例1]中对象obj被如下使用:
void main()
{
  integ  obj;                                          //建立对象并初始化
  cout << obj.read() << endl;          //读数据
  cout << obj.sq( ) << endl;                   //读平方值
}
/* Results:
6
36   */

其中分别读对象obj的数据成员j值以及求j的平方值。
从主函数可以看出,调用对象成员时,使用成员访问符(access operator)“ . ”。此处obj.read()和obj.integ::read( )的表达式是相同的。
对象可具有名称、指针和引用。在访问对象成员时可使用不同成员访问符。见下例。
[例1]分别使用对象的名称和指针来使用(访问)对象成员的例子
// access operators(成员访问符) . and ->
#include <iostream.h>
class Count {
public:
     int x;
     void print() { cout << x << endl; }
};
void main()
{
   Count obj,                   // create obj object
   *objPtr = &obj,           // pointer to obj
          &objRef = obj;   // reference to obj
            //使用对象名//
          obj.x = 7;       // assign 7 to data member x
          cout << "Display x using the object's name: ";
          obj.print();     // call member function print
                 //使用引用//
          objRef.x = 8;    // assign 8 to data member x
          cout << "Display x using a reference: ";
          objRef.print();
                 //使用指针//
          objPtr->x = 10;  // assign 10 to data member x
          cout << "Display x using a pointer: ";
          objPtr->print();
              //请注意:对象的指针可直接指向对象的成员
}

/* Results:
Display x using the object's name: 7
Display x using a reference: 8
Display x using a pointer: 10
*/
对象的内存数据存储空间分为两部分:即内存栈区空间以及内存数据区空间。统称为“双区存储空间”。
一个对象被建立后,绝大多数情况下被存储于内存栈区空间内。(个别情况下,如整个对象是静态的,则它被存储于内存数据区空间内)。在该内存栈区空间内存储的是该对象的非静态数据。而该类的(供所有对象所共享)静态数据则存储于内存数据区空间内。
[例2]确定对象大小和各种变量的地址
#include "iostream.h"
class base {
public:
       int x1;
       static double s;
       int inc( ) { return x1++; }
       // To show that inc( ) does not occupy space in stack area
};
double base::s = 1.1;               //类的静态数据必须说明或定义
void main()
{
              // To show an object only contains non-static datum
       cout<< "size of class base is "<< sizeof(base) << endl;
       cout<< "equal to size of an integer:"<< sizeof(int) << endl;
              //To show that static datum occupies space in data area
       cout<< "address of static base::s is "<< &base::s <<endl;
   // To show only non-static datum occupies space in stack area
       base p;
       cout<< "address of object p is "<< &p <<endl;
       cout<< "address of p.x1 is "<< &p.x1 <<endl;
}
/* Results:
size of class base is 4
equal to size of an integer:4(函数和静态数据都不在本对象内)
address of static base::s is 0x00429098(在数据区内)
address of object p is 0x0012FF7C(在栈区内)
address of p.x1 is 0x0012FF7C(在栈区的同一地址内)
*/

C++语言中对象的具体定义:
类是包含数据(属性,Attributes)和对这些数据进行操作的函数(实现,Implementation)这两部分的实体(entity)。类的实例(instance)是对象(object)。
前面提到过,一个对象被建立后,至少被存储于两个内存存储空间内。其中内存栈区空间用于存储每个对象的非静态数据;内存代码空间(代码区)用于存储类的成员函数的代码。
如果对象中包括静态数据,则它被存放在内存数据区空间内。
如果类中包括虚函数,则内存栈区空间内还存放该对象的虚指针,内存数据区空间内还存放该对象的虚地址表。
上面[例2]中的程序obj_cont_1.cpp所确定的对象大小(长度)是该具体对象的内存栈区空间的长度而不包括其它内存空间。
对象的长度一般是其最长数据成员长度的整数倍。如果对象是空的,则系统为它分配一个字节的空间。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics