精华内容
下载资源
问答
  • 文章目录五、对象数组和对象指针1. 对象数组的定义和使用2. 指向对象的指针3....在建立对象数组的时候需要调用构造函数,有多少个对象就要调用多少次构造函数 如果对象数组所属类有带参数的构造函数,可用初

    五、对象数组和对象指针

    1. 对象数组的定义和使用

    • 将具有相同类类型的对象有序的集合在一起构成了对象数组,以一维对象数组为例,定义形式为:

      Point points[100]; //类名 对象数组名[常量表达式];
      

    说明:

    1. 在建立对象数组的时候需要调用构造函数,有多少个对象就要调用多少次构造函数

    2. 如果对象数组所属类有带参数的构造函数,可用初始化列表按顺序调用构造函数,使用复制初始化来初始化来初始化每个数组元素

    3. 如果对象数组所属类有单个参数时,定义数组时可以直接在初始化列表中提供实参

      Point P[3] = {Point(1,2), Point(5, 6), Point(7,8)};
      Student S[5] = {20, 21, 19, 20, 19}; // Student类只有一个数据成员
      
    4. 对象数组创建时若没有初始化,则其所属类要么有合成默认构造函数,要么定义无参数的构成函数或全部参数为默认参数的构造函数

    5. 对象数组的初始化究竟是什么形式,本质上取决于所属类的构造函数

    6. 如果对象数组含有析构函数,那么建立对象数组时按每个元素出现的顺序调用构造函数,按相反的顺序调用析构函数

    2. 指向对象的指针

    • 对象内存单元的起始地址就是对象的指针,可以定义一个指针变量,用来存放对象的指针,指向类对象的指针变量的定义为

      类名 * 对象指针变量名 = 初值;
      
      
    • 示例

      class Time{
      public:
          Time(int h=0, int m=0, int s=0): hour(h), minute(m), second(s) { }
          void set(int h=0, int m=0,int s=0)
          {
              hour=h;
              minute=m;
              second=s;
          }
          int hour, minute, second;
      };
      int main()
      {
          Time now(12, 0, 0), *pt;
          pt=&now;
          return 0;
      }
      
    • 可以通过对象指针访问对象和对象的成员。

      pt->set(13, 13,0);
      pt->hour =1;
      

    3. 类成员指针

    • 对象的成员也要占用存储空间,因此可以使用指向对象成员的指针变量,一般形式为

      int *ptr = &now.hour; // 数据成员类型 *指针变量名 = 初值;
      
    • 指针可分为四类

      • C语言的普通指针:数据指针、函数指针
      • C++的成员指针:数据成员指针、成员函数指针
    • 成员指针与类的类型和成员的类型相关,可用来指向类的非静态成员,因为静态成员不属于任何类的对象,可用普通指针

    数据成员指针
    • 定义数据成员指针的一般形式为:

      数据成员类型 类名::*指针变量名 = 成员地址初值;
      
    • 示例

      class Data{
      public:
          typedef unsigned int index; // 类型成员
          char get() const; // 成员函数
          char get(index st, index eb) const; // 成员函数
          string content; // 数据成员
          index cursor, top, bottom; // 数据成员
      };
      
      int main()
      {
      	string Data::*ps = &Data::content; // 指向Data::content的成员指针   
      }
      
    成员函数指针
    • 定义成员函数指针时必须保证三个方面与其所指的函数的类型相匹配

      • 成员函数的形参类型和数目,包括成员是否为const
      • 返回类型
      • 类类型

      定义形式如下:

      //返回类型 (类名::*指针变量名)(形参表) = 成员地址初值
      //  或
      //返回类型 (类名::*指针变量名)(形参表)const = 成员地址初值
      
      char (Data::*pmf)() const = &Data::get; //指向Data::get()的成员函数指针
      
      typedef char (Data::*GETFUNC)(Data::index, Data::index)const; // 为成员指针使用类型别名
      GETFUNC pfget = &Data::get; //定义成员函数指针
      
    使用类成员指针
    • 通过对象成员指针引用 类类型对象.*成员指针

    • 通过指针成员指针引用 类类型指针->成员指针

    • 示例

      Data d, *p=&d; // p是指向对象d的指针
      int Data::*pt = &Data::top; // pt是指向数据成员top的成员指针
      int k = d.top; // 对象成员引用,直接访问对象,直接访问数据成员
      k = d.*pt; // 对象成员指针引用,直接访问对象,间接访问数据成员
      k = p->top; // 指针成员引用,间接访问对象,直接访问数据成员
      k = p->*pt; // 指针成员指针引用,间接访问对象,间接访数据成员
      char (Data::*pmf)(int, int) const; // pmf为成员函数指针
      pmf = &Data::get; // 指向有两个参数的get函数
      char c1 = d.get(0, 0); // 对象直接调用成员函数,与下面等价
      char c2 = (d.*pmf)(0, 0); // 对象通过成员函数指针间接调用成员函数
      char c3 = (p->*pmf)(0, 0); // 指针间接引用对象通过成员函数指针间接调用成员函数
      

    4. this指针

    • 除了静态成员函数外,每个成员函数都有一个隐含的、额外的形参this,在调用成员函数时,编译器向形参this传递调用该成员函数的对象的地址

      void Point::set(int a, int b) { x = a; y = b;}
      
      // 编译器将上述函数重写为
      void Point::set(Point* const this, int a, int b)
      {
          this->x = a;
          this->y = b;
      }
      
    • 对应的函数调用

      one.set(10,10);
      Point::set(&one, 10, 10);
      
    • 示例

      #include <iostream>
      #include <string.h>
      using namespace std;
      class Point
      {
      public:
          Point(int a, int b) { x = a; y = b;}
          void MovePoint(int a, int b) { x += a; y += b;}
          void print() { cout << "x=" << x << ", y=" << y << endl;}
      
      private:
          int x, y;
      };
      
      int main()
      {
          Point pt1(10, 10);
          pt1.MovePoint(2, 2);
          pt1.print();
          return 0;
      }
      

      解读:

      1. 当对象pt1调用MovePoint(2,2)函数时, 即将pt1对象的地址传递给了this指针,即如下

        void MovePoint(Point *const this, int a, int b);
        
      2. MovePoint函数便成了

        void MovePoint(int a, int b) 
        { 
            this->x += a; 
            this->y += b;
        }
        
    • 什么时候用到this指针

      • 在类的非静态成员函数返回类对象成员本身的时候,直接使用return *this
      • 当参数与数据成员名相同时,如this->n = n
      class Point{
      public:
          Point(float x, float y)
          {
              this->x = x;
              this->y = y;
          }
      private:
          float x, y;
          
      }
      
    • this指针的const限定

      • 假设Point类有getX这样一个非静态函数

        double Point::getX();
        
        // 编译后
        double getX(Point *const this); // this指针的指向不允许改变,所以this指针原本就是const指针
        
      • 如果成员函数是常函数

        double Point::getX()const;
        
        // 编译后
        
        double getX(const Point *const this); //既不允许this指针的指向,也不允许改变this指向的内容
        
    展开全文
  • C++的构造函数在创建对象时调用,分配内存空间,多少个对象(对象数组)就调用次构造函数;析构函数在调用结束时调用(可以添加一些最后的处理)以释放内存给其它来用。对于同类型同生命期的对象,先创建的对象,...

    C++的构造函数在创建对象时调用,分配内存空间,多少个对象(对象数组)就调用几次构造函数;析构函数在调用结束时调用(可以添加一些最后的处理)以释放内存给其它来用。对于同类型同生命期的对象,先创建的对象,先调用构造函数,但调用析构函数顺序在最后。

    构造函数可以有多个(重载),构造函数也可以带参数(也可以设置默认值(相当于多个重载函数,所以有默认值参数的构造函数就不要在重载多个了否则会出错))从而可以给不同对象传递不同参数,参数的赋值可以在类定义中进行".cpp",也可以在类对象声明中用列表化传递,参数也可以只给类型。

    析构函数只有一个不能重载,对象的析构顺序和构造顺序相反。

    对象数组的初始化方法:当构造函数只有一个参数时可以“大括号逗号隔开”,当构造函数参数有多个时可以用“大括号中构造函数(参数列表1),构造函数(参数列表2),,,构造函数(参数列表n)}"

    指针:

    类对象也可以有指针,用以指向对象的首地址;

    类对象的数据成员也可以有指针,和一般类型对象指针没有什么区别。

    类对象的函数成员的数据指针与一般的函数指针不同,声明方法:返回值类型(类型::*pfun)(参数列表)=&类名::函数(),注意因为类的函数成员是对所有的对象的,所以指针也要指向类的函数而非对象的函数,但调用时要用"对象.*pfun()"

    this指针:是隐式的默认传递的,所以不同对象调用同类的成员函数时系统能区分调用的是哪个对象的数据成员,当然也可以显示调用。

     

    转载于:https://www.cnblogs.com/jieruishu/p/9961661.html

    展开全文
  • c++学习之对象的应用

    2017-10-19 16:10:17
    1.对象数组-定义Square obj[3] = { Square(1), Square(2),Square(3)}构造:有多少个数组元素,则调用多少次构造函数-访问 对象数组名【下标】.公有成员名cout [n] ;析构:有多少个数组元素,则调用多少次析构函数2...

    1.对象数组

    -定义

    Square obj[3] = { Square(1), Square(2),Square(3)}

    构造:有多少个数组元素,则调用多少次构造函数

    -访问
    对象数组名【下标】.公有成员名

    cout << obj[n] <<endl;

    析构:有多少个数组元素,则调用多少次析构函数

    2.对象的动态分配

    3.对象作为函数的形参
    -值传递与常对象

    常对象定义时必须赋初值

    double InnerCircleArea( const Square s ) // 常对象形参 
    { 
    …… 
    }

    -引用传递和常引用

    double InnerCircleArea( Square &s ) // 引用传递
    {
    double r = s.a / 2;
    return (3.14*r*r);
    }
    cout << InnerCircleArea( obj ) << endl;

    建议定义常引用:

    double InnerCircleArea( const Square &s ) { …… }//常引用

    -指针传递与只想常引用的指针

    double InnerCircleArea( Square *s ) // 指针传递 
    { 
    double r = s->a / 2; 
    return (3.14*r*r); 
    } 

    调用方法:

    cout << InnerCircleArea( &obj ) << endl; 
    
    double InnerCircleArea( const Square *s ) { …… }
    展开全文
  • 类学习三

    2016-03-20 21:13:28
    在建立对象数组的时候,数组的长度是多少就调用多少次构造函数为什么要使用对象数组? 答:当初始化对象很多的时候就要声明好多个对象,而使用数组只需要声明一次就搞定了,虽然内存空间上依旧还是那么多,构造和析

    类学习三(红皮书P83-P90)

                                          2016.3.20
    

    一、对象数组的初始化

    把一个数组声明为类对象,则这个数组就是对象数组。
    在建立对象数组的时候,数组的长度是多少就调用多少次构造函数

    为什么要使用对象数组?
    答:当初始化对象很多的时候就要声明好多个对象,而使用数组只需要声明一次就搞定了,虽然内存空间上依旧还是那么多,构造和析构的函数的调用次数也一致。

    对于默认的没有形参的构造函数来说,给数组初始化直接用一个花括号括起来就可以了,例如:
    Student stud[3]={2,4,3};
    则赌赢的数组的每一项都初始化

    但是如果调用的构造函数是带参数表的,则不能由上面的方法初始化,容易引起混淆,导致结果错误。那么:
    怎样对引用带形参的构造函数的对象数组进行初始化呢?
    如下:

    若其构造函数是含三个参数的:
    形如:Student (int int int),则:
    初始化:
    Student stud[3]={
        Student(10,2,3),
        Student(11,3,2),
        Student(12,4,3),
    };

    二、指向成员对象的指针

    1、概念:
    对象有地址,在前面类学习一里面的存储结构里有详细的说明,而存放对象起始地址的指针变量就是成员对象的指针变量对象中的成员也有起始地址,而存放对象成员起始地址的指针变量就是 指向对象成员的指针变量

    2、定义:
    1、定义对象数据成员的指针: 没什么好说的,正常。

    int *p1;
    p1 = &time.hour;

    2、定义类对象的指针变量
    首先申请一指针,是类类型的,然后指向所要指向的对象就行了。

    Time *p2;
    p2=&time;
    p2->get_time();//这时候的*p2相当于这个对象,访问其函数

    3、定义类公有成员函数的指针变量:
    指针指向的成员函数不能直接用等于号,普通函数的指针声明:

    void (*p)();//声明指针函数
    p=fun;//指向fun这个函数,直接用等于号
    (*p)();//代表着fun这个函数

    然而:
    类公有成员函数的指针变量不能直接这样做。
    1、先声明类指针;
    2、将指针指向具体的成员函数;

    void(Time::*p3)();
    p3=&Time::get_time;//这时候的p3才相当于是这个get函数
    (t1.*p3)();//访问其函数

    三、 this指针

    每个成员函数都包含着一个特殊的指针,就是this指针。
    它指向本类的对象,他的值是当前所调用的对象的起始地址。
    都是编译系统自动实现的。
    例:

    return (high*width*lenth);
    等价于:
    return(this->high*this->width*this->lenth);


    调用对象的成员函数就是调用this指针,并且this指针指向了要调用的对象

    先写到这里吧,今天的进度比较慢,明天继续。接下来再写一个程序就可以回去了,今天有时圆满的一天。

    展开全文
  • jsp九大内置对象

    2011-10-21 23:25:22
     调用Cookie对象构造函数就可以创建Cookie对象。Cookie对象构造函数有两个字符串参数:Cookie名字和Cookie值。  例如:Cookie c = new Cookie("username","john");  (3)将Cookie对象传送到客户端  在...
  • 【05-面向对象(下)】

    2018-07-03 21:42:31
    抽象类里可以包含构造器,抽象类里的构造器并不是用于创建对象,而让其子类调用这些构 造器来完成属于抽象类的初始化操作。 •接口里不能包含初始化块,但抽象类则完全可以包含初始化块。 •一个类最多只能有一个...
  • 1.  虚继承的目的是令某个类... MyClass *b[6]是一个指针数组数组里面存放的是MyClass类型的指针,即存放的地址,故不会调用该类的构造函数。 (例:MyClass (*p)[6]是一个数组指针,也不会调用该类的构造函...
  • 你必须知道的495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    1.25 函数只定义了一调用了一,但编译器提示非法重声明了。 *1.26 main的正确定义是什么?voidmain正确吗? 1.27 我的编译器总在报函数原型不匹配的错误,可我觉得没什么问题。这是为什么? 1.28 文件...
  • 1.25 函数只定义了一调用了一,但编译器提示非法重声明了。 43 *1.26 main的正确定义是什么?void main正确吗? 44 1.27 我的编译器总在报函数原型不匹配的错误,可我觉得没什么问题。这是为什么? 44 ...
  • 1.25 函数只定义了一调用了一,但编译器提示非法重声明了。 43 *1.26 main的正确定义是什么?void main正确吗? 44 1.27 我的编译器总在报函数原型不匹配的错误,可我觉得没什么问题。这是为什么? 44 ...
  • 1.25 函数只定义了一调用了一,但编译器提示非法重声明了。  *1.26 main的正确定义是什么?voidmain正确吗?  1.27 我的编译器总在报函数原型不匹配的错误,可我觉得没什么问题。这是为什么?  1.28 ...
  •  声明问题 1.25 函数只定义了一调用了一,但编译器提示非法重声明了。 *1.26 main的正确定义是什么?voidmain正确吗? 1.27 我的编译器总在报函数原型不匹配的错误,可我觉得没什么问题。这是为什么?...
  • 1.25 函数只定义了一调用了一,但编译器提示非法重声明了。 14 *1.26 main的正确定义是什么?void main正确吗? 15 1.27 我的编译器总在报函数原型不匹配的错误,可我觉得没什么问题。这是为什么? 15 ...
  • 《你必须知道的495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    1.25 函数只定义了一调用了一,但编译器提示非法重声明了。 14 *1.26 main的正确定义是什么?void main正确吗? 15 1.27 我的编译器总在报函数原型不匹配的错误,可我觉得没什么问题。这是为什么? 15 ...
  • o 2.8 函数只定义了一, 调用了一, 但编译器提示非法重定义了。 o 2.9 main() 的正确定义是什么? void main() 正确吗? o 2.10 对于没有初始化的变量的初始值可以作怎样的假定?如果一个全局变量初始值为 ``...
  • 6、编写类String的构造函数、析构函数和赋值函数(25分) 已知类String的原型为: class String { public: String(const char *str = NULL);//普通构造函数 String(const String &other);//拷贝构造函数 ~ String...
  • 面向对象的软件工程是面向对象方法在软件工程领域的全面应用,它包括面向对象的分析(OOA)、面向对象的设计(OOD)、面向对象的编程(OOP)、面向对象的测试(OOT)和面向对象的软件维护(OOSM)等主要内容。...
  • 不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。  接口(interface...
  • JAVA面试题最全集

    2010-03-13 13:09:10
    给定一个C语言函数,要求实现在java类中进行调用。 45.如何获得数组的长度? 46.访问修饰符“public/private/protected/缺省的修饰符”的使用 47.用关键字final修饰一个类或者方法时,有何意义? 48.掌握类和...
  • 面试题9:简述子类与父类的析构、构造函数调用顺序 面试题10:编写类String 的构造函数、析构函数和赋值函数 8.4 拷贝构造函数 面试题11:谈谈对拷贝构造函数和赋值运算符的认识 面试题12:写出当定义#define _...
  • java 面试题 总结

    2009-09-16 08:45:34
    不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 接口(interface)...
  • 构造函数: public function AbstractCollection() 方法: addConstraint () 方法 public function addConstraint(c:AbstractConstraint):void 在收集器中增加一个约束。 参数 c:AbstractConstraint — 被加入的约束...
  • 4.1.4 讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当new的时候,他们的执行顺序。 4.1.5 用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么...

空空如也

空空如也

1 2 3 4
收藏数 72
精华内容 28
关键字:

对象数组调用多少次构造函数