精华内容
下载资源
问答
  • 构造函数的作用:初始化 visual studio按下ctrl + F5进行运行,F9可以设置断点,可以单步调试,再按下F5进行调试,单步跟踪按下F11,F10不会跟踪到函数内部 结束程序的按钮如下: 构造函数运行被重载 ~表示取反 ...

    1.构造函数

    • 构造函数是特殊的成员函数
    • 创建类类型的新对象,系统自动会调用构造函数
    • 构造函数是为了保证对象的每个数据成员都被正确初始化
    • 构造函数的作用:初始化
    • 特点:
      (1)函数名和类名完全相同
      (2)不能定义构造函数的类型(返回类型),也不能使用void
      (3)通常情况下构造函数应声明为公有函数,否则它不能像其他成员函数那样被显式地调用
      (4)构造函数被声明为私有,会有特殊的用途。
      (5)构造函数可以有任意类型和任意个数的参数,一个类可以有多个构造函数(重载)

    2.默认构造函数

    • 不带参数的构造函数
    • 如果程序中未声明,则系统自动产生出一个默认构造函数

    3.重载构造函数

    • vs的使用技巧
      visual studio按下ctrl + F5进行运行,F9可以设置断点,可以单步调试,再按下F5进行调试,单步跟踪按下F11(不需要跟踪,就按下shift F11),F10不会跟踪到函数内部
      结束程序的按钮如下:
      在这里插入图片描述
      用vs每次调试的时候,注意是这样调试。其他的文件要从项目中排除

    在这里插入图片描述

    • eg:11cpp\11cpp\11cpp\01.cpp
      构造函数运行时,被重载
    #include "Test.h"
    
    int main(void)
    {
    	//构造函数被重载
    	//t和t2是栈上的内存,其作用域在花括号内,当程序跳出花括号,就要释放这俩对象
    	//t和t22内存释放的顺序与创建的顺序相反
    	Test t;//新建一个对象的时候,构造函数会被自动调用
    	t.Display();
    
    	Test t2(10);
    	t2.Display();
    
    	//定义一个动态对象,会调用带一个参数的构造函数
    	//new与malloc的区别:不仅分配内存,还调用了构造函数,所以称之为:new operator
    	//t3是堆内存
    	Test* t3 = new Test(20);
    	t3->Display();
    
    	//delete不仅释放内存,还调用了析构函数
    	delete t3;//动态分配的内存需要自己释放
    
    	
    	return 0;
    }
    
    • 类的定义及声明
      (1)11cpp\11cpp\11cpp\Test.h
    #ifndef _TEST_H_
    #define _TEST_H_
    
    class Test
    {
    public:
    	// 如果类不提供任何一个构造函数,系统将为我们提供一个不带参数的
    	// 默认的构造函数
    	Test();//若将Test()声明为private的,说明在外部不可见,连main函数都看不到,编译都不会通过
    	Test(int num);//提供一个带参数的构造函数,则系统也不再提供一个不带参数的默认构造函数了
    	void Display();
    
    
    	//析构函数不能被重载,意味着析构函数不能有参数
    	~Test();
    private:
    	int num_;
    };
    #endif // _TEST_H_
    

    (2)11cpp\11cpp\11cpp\Test.cpp

    #include "Test.h"
    #include <iostream>
    using namespace std;
    
    // 不带参数的构造函数称为默认构造函数
    Test::Test()
    {
    	num_ = 0;
    	cout<<"Initializing Default"<<endl;
    }
    
    Test::Test(int num)
    {
    	num_ = num;
    	cout<<"Initializing "<<num_<<endl;
    }
    
    Test::~Test()
    {
    	cout<<"Destroy "<<num_<<endl;
    }
    
    void Test::Display()
    {
    	cout<<"num="<<num_<<endl;
    }
    
    • 测试:
      在这里插入图片描述

    4.构造函数与new

    看上面的例子

    5.全局对象的构造先于main函数

    • eg:11cpp\11cpp\11cpp\02.cpp
    #include "Test.h"
    #include <iostream>
    using namespace std;
    
    Test t(10);
    
    int main(void)
    {
    	cout<<"Entering main ..."<<endl;
    	cout<<"Exiting main ..."<<endl;
    	return 0;
    }
    
    • 类的声明及定义如上

    6.析构函数

    • 函数名和类名相似(前面多了一个字符“~”),~表示取反
    • 没有返回类型
    • 没有参数
    • 析构函数不能被重载
      如果没有定义析构函数,编译器会自动生成一个默认析构函数,其格式如下:
    类名::~默认析构函数名( )
    {
    }
    默认析构函数是一个空函数。
    
    • eg看上面

    7.析构函数与数组

    • eg:11cpp\11cpp\11cpp\03.cpp
    #include "Test.h"
    
    int main(void)
    {
    	//创建了一个对象数组,其中有两个对象,会调用2次构造函数
    	//当数组t生命周期结束的时候,会调用析构函数
    	Test t[2] = {10, 20};
    
    	//创建一个test对象,传递参数2
    	Test* t2 = new Test(2);
    	delete t2;
    
    	//这里相当于没有传递任何参数,创建了2个对象,调用默认构造函数
    	Test* t3 = new Test[2];
    	delete[] t3;//若创建的是数组:Test[2],delete的中括号不要省略
    	//delete不仅调用析构函数,还会对内存进行释放
    	return 0;
    }
    
    • 类的定义及声明见上面
    • 测试:
      在这里插入图片描述

    8.析构函数与delete运算符

    8.析构函数可以显式调用

    • eg:11cpp\11cpp\11cpp\04.cpp
    #include "Test.h"
    
    int main(void)
    {
    	//构造函数无法显式调用,析构函数可以显式调用,但一般很少用。
    	Test t;
    	t.~Test();	
    	return 0;
    }
    
    • 类的声明以及定义见上
    • 测试:
      析构函数显示调用,只在特殊场合才这么做

    在这里插入图片描述

    展开全文
  • C++对象数组调用构造/析构函数的方法

    千次阅读 多人点赞 2016-09-20 23:35:25
    C++的对象数组: 顾名思义,即是存储对象的数组。比如有一个对象student,实例化为对象数组...//第二种方法,在堆空间中分配空间对象数组调用构造函数:class student //定义一个student类,只有个构造函数当示例用 { pu

    C++的对象数组:
    顾名思义,即是存储对象的数组。比如有一个对象student,实例化为对象数组有如下两种方式:

    student stu[3];  //第一种方法,在栈空间中占用内存
    student *stu = new student[3];//第二种方法,在堆空间中分配空间

    对象数组调用构造函数:

    class student   //定义一个student类,只有个构造函数当示例用
    {
        public:
            student(string name, int age)
            {
                stu_name = name;
                stu_age = age;
            }
        private:
            string stu_name;
            int stu_age;
    };
    int main()
    {
        student stu1[3] = student("小明",12); //调用构造函数把三个对象的stu_name和stu_age都初始化为"小明"和12
        student stu2[3] = {student("小明",12),student("小王",13),student("小李",14)};//把三个对象的stu_name和stu_age分别初始化为"小明",12和“小王”,13和"小李",14
        student *stu3[3]; //定义一个指针数组对象
        for(int i = 0; i < 3; i++) //循环依次实例化
        {
            stu3[i] = new student("小明",12); //调用构造函数
        }
    }

    调用析构函数:
    在对象stu1和stu2这两个对象数组中是不需要释放内存的,栈空间的内存系统自动释放,所以在析构函数中并不需要写什么;但是在堆空间中,由于使用了new操作符来申请内存,所以需要程序员手动释放。紧接着上面的代码,如下:

    for(int i = 0; i < 3; i++)  //由于创建的是指针数组,所以需要循环释放内存
    {
        delete stu3[i];
    }

    注意:
    如果构造函数里面没有传任何参数,那么使用new操作符可以进行如下不同于上面的实例化对象和释放内存操作

    student *stu4 = new student[3]; //实例化对象数组
    delete []stu4;   //释放内存
    
    展开全文
  • 一、析构函数也是一种特殊的成员函数,也被声明为公有成员。 析构函数的特点: (1)析构函数的名字必须与类名相同,...(4)当撤销对象时,系统会自动调用析构函数完成空间的释放和善后工作。 析构函数的定义格式如

    一、析构函数也是一种特殊的成员函数,也被声明为公有成员。

    析构函数的特点:

    (1)析构函数的名字必须与类名相同,但在名字面前要加上~。

    (2)析构函数没有返回值类型说明,也不能被指定为void类型,函数体中不能有return语句。

    (3)析构函数没有参数,不能重载,在一个类中只能有一个析构函数。

    (4)当撤销对象时,系统会自动调用析构函数完成空间的释放和善后工作。

    析构函数的定义格式如下:

    类名::~类名()

    {

    //析构函数体

    }

    二、对象数组和对象指针

    1、一维对象数组的定义:类名    数组名【数组长度】;

    例如:student  obj[10];定义了student的对象数组obj,这个数组中包含了10个student类的对象 obj[0]~obuj[9].

    2、一维对象数组的访问

    在使用对象数组时也只能访问某个数组元素,也就是一个对象,通过这个对象,也可以访问到它的公有成员,一般格式:

    数组名【下标】.成员名

    展开全文
  • 2、在对象生存周期结束之后系统会自动调用析构函数,然后释放此对象的空间; 3、如果程序没有声明构造函数,系统会默认自动产生一个隐含的构造函数; 4、析构函数只能有一个,析构函数不能传递任何参数,没有返回...

    一、c++中析构函数的主要作用:

    1、完成对象被删除前的的一些清理工作;

    2、在对象生存周期结束之后系统会自动调用析构函数,然后释放此对象的空间;

    3、如果程序没有声明构造函数,系统会默认自动产生一个隐含的构造函数;

    4、析构函数只能有一个,析构函数不能传递任何参数,没有返回类型。

    5、使用构造函数和析构函数时,注意先后的使用顺序,注意调用时间和调用顺序,在一般情况下,调用析构函数的次序正好和调用析构函数的次序相反;【待会儿介绍另外的情况,在堆中程序员自己决定释放调用构造函数的时机】

    二、实例说明:以Box类为例说明

    1、构造函数重载:主要是理解无参和有参数的构造函数

       //1、对于一般函数,定义之后就会调用构造函数(无参数的构造函数)
    	Box box1;   
    	cout <<"The volume of box1 is :" << box1.volume()<<endl;
        //2、定义后就会调用构造函数,调用含参数的构造函数
    	Box box2(15,12,13); 
    	cout <<"The volume of box2 is :" << box2.volume()<<endl;

    2、对象动态数组new在类中的使用:

    // 3、 对于堆指针,定义后不会调用默认的构造函数
    	Box *box3;
    
        // 4、 对于堆指针,定义后不会调用默认的构造函数,但是在初始化之后会调用构造函数(此时调用无参的构造函数)
    	Box *box4= new Box; 
    	cout <<"The volume of box4 is :" <<box4->volume()<<endl;
    	
    
    	// 5、 对于堆指针,定义后不会调用默认的构造函数,但是在初始化之后会调用构造函数(此时调用无参的构造函数)
    	Box *box5= new Box(11,11,11); 
    	cout <<"The volume of box5 is :" <<box5->volume()<<endl;

    3、类的对象数组

    
    	//6、定义一个数组
    	Box box6[3]={ Box(3,3,3),
    		          Box(4,4,4),
    				  Box(5,5,5)
    	             }; //调用默认的构造函数三次,同理析构函数也是三次
    	cout <<"The volume of box6[0] is :" <<box6[0].volume()<<endl;
    	cout <<"The volume of box6[1] is :" <<box6[1].volume()<<endl;
    	cout <<"The volume of box6[2] is :" <<box6[2].volume()<<endl;
    

    4、构造函数的析构顺序:(1)先析构堆中的内存,由程序员完成,而且是先释放的先调用析构函数,譬如:本例中先释放delete box5,会先调用析构函数(box5);(2)然后在析构数组(3个类成员)(3)按照先调用构造函数后析构的准则完成

    //6、构造函数的使用与什么时候释放相关,先释放的先析构,后释放的后析构
    	cout <<"\t先由程序员析构堆中内存:"<<endl;
    	delete box5;
    	delete box4;
    	cout <<"\t再析构其它:"<<endl;

    三、完整的程序代码如下:

    #include "iostream"
    using namespace std;
    
    //构造函数的重载,析构函数不可以重载
    class Box
    {
    public:   
    	Box();//无参的构造函数
    	Box(int length,int width,int height);//有参数的构造函数
    	~Box();  //调用析构函数
    	int volume(); //成员函数器求体积
    private:
    	int length;
    	int width;
    	int height;
    };
    
    Box::Box()
    {
    	length = 10;
    	width =10;
    	height =10;
    	cout << "无参的构造函数被调用:Box()"<<endl; 
    
    }
    Box::Box(int length,int width,int height):length(length),width(width),height(height)    //有参数的构造函数,通过初始化列表赋值
    { cout << "含参的构造函数被调用:Box(int length,int width,int height)"<<endl; }
    
    Box::~Box() //调用析构函数
    {
       cout << "析构函数被调用:~Box():"<<"此时的volume: "<< this->volume()<<endl; 
    }
    
    int Box::volume()//成员函数器求体积
    {
       return (height*width*length);
    }
    
    int main()
    {
    	//1、对于一般函数,定义之后就会调用构造函数(无参数的构造函数)
    	Box box1;   
    	cout <<"The volume of box1 is :" << box1.volume()<<endl;
        //2、定义后就会调用构造函数,调用含参数的构造函数
    	Box box2(15,12,13); 
    	cout <<"The volume of box2 is :" << box2.volume()<<endl;
    
    	cout<<"\n*********************************************reference(引用)************************************\n"<<endl;
    
    	// 3、 对于堆指针,定义后不会调用默认的构造函数
    	Box *box3;
    
        // 4、 对于堆指针,定义后不会调用默认的构造函数,但是在初始化之后会调用构造函数(此时调用无参的构造函数)
    	Box *box4= new Box; 
    	cout <<"The volume of box4 is :" <<box4->volume()<<endl;
    	
    
    	// 5、 对于堆指针,定义后不会调用默认的构造函数,但是在初始化之后会调用构造函数(此时调用无参的构造函数)
    	Box *box5= new Box(11,11,11); 
    	cout <<"The volume of box5 is :" <<box5->volume()<<endl;
    
    	cout<<"\n*********************************************array(数组)************************************\n"<<endl;
    
    	//6、定义一个数组
    	Box box6[3]={ Box(3,3,3),
    		          Box(4,4,4),
    				  Box(5,5,5)
    	             }; //调用默认的构造函数三次,同理析构函数也是三次
    	cout <<"The volume of box6[0] is :" <<box6[0].volume()<<endl;
    	cout <<"The volume of box6[1] is :" <<box6[1].volume()<<endl;
    	cout <<"The volume of box6[2] is :" <<box6[2].volume()<<endl;
    
    
        cout<<"\n*************************************注意析构函数(desconsructor)的调用顺序:**************************\n"<<endl;
    
    	//6、构造函数的使用与什么时候释放相关,先释放的先析构,后释放的后析构
    	cout <<"\t先由程序员析构堆中内存:"<<endl;
    	delete box5;
    	delete box4;
    	cout <<"\t再析构其它:"<<endl;
    
    	return 0;
    }

    运行结果如下:

     

    展开全文
  • 这是我们要通过基类指针维护对象表时必须要考虑的细微但重要的一点,如果基类的析构函数不是虚函数,则用基类指针指向的派生类对象析构函数得不到执行,那么有派生类所生成的动态数据将得不到释放。 请看下面的...
  • 构造函数函数名和类名完全相同不能定义构造函数的类型(返回类型),也不能使用void 通常情况下构造函数应声明为公有函数,否则它不能像其他成员函数那样被显式地调用构造函数被声明为私有有特殊的用途。构造函数...
  • C++虚析构函数、纯虚析构函数

    千次阅读 2016-03-01 18:18:44
    因为在C++中,当一个派生类对象通过使用一个基类指针删除,而这个基类有一个非虚的析构函数,则结果是未定义的。运行时比较有代表性的后果是对象的派生部分不会被销毁。然而,基类部分很可能已被销毁,这就导致了一...
  • 编程语言中为什么要区分数据类型? 基于存储空间和运算速度的考虑,都定义为容量最大的,耗费的存储空间自然要大许多,小程序不明显,程序规模大的话,这就是问题了,再者,...组成数组的各个变量称为数组的分量,...
  • 析构函数 就是 向派生类传递的析构结构 虚函数 是从顶部向下传递 虚析构函数是从底部向上传递的 基类是顶层 #include <iostream> #include <string> using namespace std; class A{ public: A() = ...
  • C++的对象数组 顾名思义,即是存储对象的数组。...对象数组调用构造函数及析构函数 例子1 class A { public: A() { cout << "A()" << endl; } ~A() { cout << "~A()" << endl; } }; int
  • 析构函数

    2021-05-18 10:09:53
    特点 名字和类名相同, 在前面加个‘~’, 没有参数和返回值,...对象数组生命期结束时,对象数组的每个元素的析构函数都会被调用 class CTest { public : ~Ctest() { cout << "destructor called " << e
  • 1.下列哪一个是析构函数的特征() 正确答案: B A析构函数定义只能在类体内 (析构可以在类外定义) B一个类中只能定义一个析构函数 C析构函数名与类名不同 (要与类名相同, 前面加~) D析构函数可以有一个或多个...
  • C++虚析构函数与纯虚析构函数

    千次阅读 2013-07-28 20:24:07
    因为在C++中,当一个派生类对象通过使用一个基类指针删除,而这个基类有一个非虚的析构函数,则结果是未定义的。运行时比较有代表性的后果是对象的派生部分不会被销毁。然而,基类部分很可能已被销毁,这就导致了一...
  • 对象数组 任何数据类型都能定义数组 对象数组 —》多个对象组成的一个数组 Animal buf[10]; buf[0].eat(); string类常用的方法 assign() //字符串赋值 char* c_str() const; //string对象转换成C语言风格的字符...
  • 目录头文件Test.h实现文件Test.cpp构造函数默认构造函数重载构造函数构造函数与new运算符newnew operatoroperator new全局对象的构造先于main函数析构造函数析构函数与数组析构函数与delete运算符析构函数可以显示...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,259
精华内容 21,303
关键字:

对象数组的析构函数