精华内容
下载资源
问答
  • C++中建立派生类对象时构造函数的调用顺序 建立派生类对象时,派生类构造函数的调用顺序如下: 执行基类的构造函数。当派生类有多个基类,处于同一层次的各个基类的构造函数的调用顺序取决于定义派生类...
    C++中建立派生类对象时构造函数的调用顺序
    建立派生类对象时,派生类构造函数的调用顺序如下:
    1. 执行基类的构造函数。当派生类有多个基类时,处于同一层次的各个基类的构造函数的调用顺序取决于定义派生类时生命的顺序(从左至右),而与在派生类构造函数的成员初始化列表中给出的顺序无关。如果派生类的基类也是一个派生类,则每个派生类值需负责它的直接基类的构造,依次上溯。
    2. 执行成员对象的构造函数(如果有的话)。当派生类中有多个成员对象时,各个成员对象构造函数的调用顺序也取决于在派生类中定义的顺序(自上而下),而与在派生类构造函数的成员初始化列表中给出的顺序无关。
    3. 执行派生类的构造函数。
    派生类构造函数的定义中可以省略对基类构造函数的调用,其条件是基类中必须有默认的构造函数或者根本就没有定义构造函数。

    派生类析构函数的调用顺序:
    1. 执行派生类的析构函数,对派生类新增普通成员进行清理。
    2. 调用成员对象析构函数,对派生类新增的成员对象进行清理。
    3. 调用基类的析构函数,对基类进行清理。
    派生类析构函数的定义与基类无关,与没有继承关系的类中的析构函数的定义完全相同。它只负责新增成员的清理工作,系统会自己调用基类及成员对象的析构函数进行相应的清理工作。
     
    #include <iostream>
    #include <stdio.h>
    #include<math.h>
    #include <string.h>
    
    using namespace std;
    
    class BaseA
    {
    public :
        BaseA(int i)
        {
            a=i;
            cout<<"BaseA 's constructor called!"<<endl;
        }
        ~BaseA(){cout<<"BaseA 's destructor called!"<<endl;}
        int GetA(){return a;}
    private:
        int a;
    };
    class BaseB
    {
    public :
        BaseB(int i)
        {
            b=i;
            cout<<"BaseB 's constructor called!"<<endl;
        }
        ~BaseB(){cout<<"BaseB 's destructor called!"<<endl;}
        int GetB(){return b;}
    private:
        int b;
    };
    class Member
    {
    public :
        Member(int i)
        {
            m=i;
            cout<<"Member 's constructor called!"<<endl;
        }
        ~Member(){cout<<"Member 's destructor called!"<<endl;}
        int GetM(){return m;}
    private:
        int m;
    };
    class Derived:public BaseB,public BaseA
    {
    public:
        Derived(int i,int j,int k,int l);
        ~Derived(){cout<<"Derived 's destructor called!"<<endl;}
        void Print()
        {
            cout<<GetA()<<","<<GetB()<<","<<mem.GetM()<<","<<d<<endl;
        }
    private:
        Member mem;
        int d;
    };
    Derived::Derived(int i,int j,int k,int l):BaseB(j),BaseA(i),mem(k)
    {
        d=l;
        cout<<"Derived 's constructor called!"<<endl;
    }
    
    int main()
    {
        Derived obj(1,2,3,4);
        obj.Print();
    	return 0;
    }
    运行结果是:
    BaseB 's constructor called!
    BaseA 's constructor called!
    Member 's constructor called!
    Derived 's constructor called!
    1,2,3,4
    Derived 's destructor called!
    Member 's destructor called!
    BaseA 's destructor called!
    BaseB 's destructor called!

    展开全文
  • C++中,类对象的建立方式有两种,一种是静态建立类对象,如A a;另一种是动态建立类对象,如A* p = new A; 这两种方式是有区别的:  静态建立类对象:是指全局对象,静态对象,以及分配栈区域内的对象,...


      在C++中,类对象的建立方式有两种,一种是静态建立类对象,如A a;另一种是动态建立类对象,如A* p = new A;


    这两种方式是有区别的:

        静态建立类对象:是指全局对象,静态对象,以及分配在栈区域内的对象,编译器对它们的内存分配是在编译阶段就完成的,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数。

        动态建立类对象:分配堆区域内的对象,编译器对他们的内存分配是在运行时动态分配的,(使用new运算符将对象建立在堆空间中。这个过程分为两步,第一步,执行operator new()函数,在对中搜索合适的内存并进行分配,第二步,调用构造函数构造对象,初始化这片内存空间。使用这种方法,间接调用类的构造函数。


    知道了这些,那么,如何限制类只能在堆上或栈上建立对象呢?


    1.只能在堆上建立对象  

        类对象只能建立在堆上,就是不能静态建立对象,即不能直接调用类的构造函数。

        很容易就想到把类的构造函数声明为私有,就无法在类的外部调用类的构造函数建立对象,只能使用new运算符来建立对象。前面已经说过,new运算符的执行过程分为两步,C++提供new运算符的重载其实只是允许重载operator new()函数,不能重载new运算符,而operator new()函数只用于分配内存,无法提供构造函数,所以,我们再定义一个GetObj函数,用于在堆上new对象,通过GetObj函数,建立的对象都是在堆上的new出来的,将函数声明为静态的,就可以通过域作用访问符访问GetObj函数,在堆上建立对象。(在C++中静态成员函数也是类函数,及这个函数不属于某个具体的对象,而是属于一个类的,这个类实例化的每个成员都可用,同时,这个类也可以直接调用这个函数而不用实例化一个对象。)

    <span style="font-family:SimSun;font-size:18px;">class BB
    {
    public:
    	static BB& GetObj(int b1 = 0,int b2 = 0)
    	{
    		return *(new BB(b1,b2));
    	}
    private:
    	BB(int b1 = 0,int b2 = 0)
    		:_b1(b1)
    		,_b2(b2)
    	{}
    	int _b1;
    	int _b2;
    };
    void Test()
    {
    	
    	BB b = BB::GetObj();
    }</span>


    网上还有一种说法,就是将析构函数声明为私有的,当对象建立在栈上面的时候,是由编译器分配内存空间

    的,调用构造函数来构造栈对象,当对象使用使用完之后编译器会调用析构函数来释放栈对象,编译器管理了对象的

    整个生命周期,如果编译器无法调用析构函数来释放空间,那会发生什么情况呢?比如,类的析构函数是私有的,编

    译器无法调用析构函数来释放内存。所以,编译器在为类对象分配栈空间的时候,会先检查类的析构函数的访问性,

    不只是析构函数,只要是非静态的函数,编译器都会检查,如果类的析构函数是私有的,那么编译器就不会在栈上位

    类对象分配内存。


    那么,到底为什么将析构函数声明为私有的就可以只在堆上建立对象呢?

    因为c++是一个静态绑定的语言,在编译过程中,所有的非虚函数都必须分析完成,即使是虚函数,也需检查可访问

    性,因此,当在栈上生成对象是,对象会自动析构,也就是说析构函数必须可访问,而对上生成对象,由于析构是由

    程序员控制,所以,就可以不用析构函数,而重新定义一个函数完成析构函数的功能,然后手动调用。

    class AA
    {
    public:
    	AA()
    	{}
    protected:
    	~AA()
    	{}
    };
    void Test()
    {
    	AA* a = new AA;
    }

    那么怎么释放它呢?  析构函数私有化的类的设计可以保证只能用new命令在堆(heap)中创建对象, 只能动态的去创建对象, 这样可以自由的控制对象的生命周期. 但是, 这样的类需要提供创建和撤销的公共接口. 

    	AA::void Destory()
    	{
    		delete this;
    	}

        上述方法的一个缺点就是,无法解决继承问题。如果A作为其它类的基类,则析构函数通常要设为virtual,然后在子类重写,以实现多态。因此析构函数不能设为private。还好C++提供了第三种访问控制,protected。将析构函数设为protected可以有效解决这个问题,类外无法访问protected成员,子类则可以访问。

    这就证明了,如果要创建一个只能在堆上建立对象的类,无论将它的构造函数声明成私有还是析构函数声明为保护都可以达到这样的目的,但是,如果将该类的构造函数或析构函数声明为保护,最好将另外一个也声明为保护,因为例如你用new创建一个对象, 却不是用delete去删除它, 而是要用destroy方法,很显然,这是一种很奇怪的使用方法,所以,如果将该类的构造函数或析构函数声明为保护,最好将另外一个也声明为保护。

    2.只能在栈上建立对象的类

    只有使用new运算符,对象才会建立在堆上,所以只要禁用new运算符就可以实现类对象只能建立在栈上,将operator new()设为私有就可以了,一定要记得,重载了new就要重载delete

    class CC
    {
    public:
    	CC()
    	{}
    	~CC()
    	{}
    private:
    	void* operator new(size_t)//重载operator new() ,注意函数返回值和参数都是固定的
    	{}
    	void operator delete(void* ptr)//也要重载operator delete()
    	{}
    };

    参考: http://blog.csdn.net/g5dsk/article/details/4775144




    展开全文
  • 创建派生类对象时,构造函数的执行顺序是: 调用构造函数先调用基类的构造函数,调用对象成员的构造函数,最后调用派生类本省的构造函数。 例: 这里插入代码片 #include <iostream > using ...

    在创建派生类对象时,构造函数的执行顺序是:
    在调用构造函数时先调用基类的构造函数,在调用对象成员的构造函数,最后在调用派生类本省的构造函数。
    例:

    #include <iostream >
    using namespace std;
    class B1
    {
    public:
     	B1() 
    	{ 
    		cout << "Construct B1"<<endl; 
    	} 
     	~B1() 
    	{ 
    		cout<< "Destruct B1" << endl; 
    	}
    };
    class B2
    {
    public:
    	B2() 
    	{ 
    		cout << "Construct B2" << endl; 
    	}
     	~B2() 
    	{ 
    		cout << "Destruct B2 " << endl; 
    	}
    };
    class D : public B2, public B1
    {
    public:
    	D() : B2( ), B1( ) 
    	{ 
    		cout << "Construct D" << endl; 
    	}
      ~D() 
    	{
    	 	cout << "Destruct D" <<endl; 
    	}
     private:
       B2  b2;
       B1  b1;
    };
    int main()
    {
     	D d;
    	return 0;  
    }
    
    

    在这里插入图片描述

    展开全文
  • 可以建立对象的情况下调用成员吗? 非静态成员不能,非静态成员是随着对象存在而产生的,没有对象也就不会存在非静态成员,静态的可以,类名::成员名方式访问。 静态的成员变量和函数存在全局段,整个程序...

    可以在不建立对象的情况下调用类成员吗?

    静态成员不能,非静态成员是随着对象存在而产生的,没有对象也就不会存在非静态成员,静态的可以,类名::成员名方式访问。

    静态的成员变量和函数存在全局段,整个程序只有一份,所以可以直接用类名来引用(C++ primer PLUS P589)。
    非静态的是没有空间的,只有实例化一个对象的时候才会有空间,所以不能用类名来引用,只能用对象来引用。
    举个例子:

    class A {
    public:
    int x;
    static int y;
    
    };
    
    A a, b;
    a.x = 10;
    b.x = 20;

    如果你用类来引用x, A::x那编译器怎么知道你要用哪个x啊,对象a也有,b也有,还可能更多。一个对象一份。当然要用对象来引用啦,a.x, b.x这样才对。
    静态的不同,不管你有多少个对象, y只有一份,存在静态区,a.y, b.y都是同一个变量。

    可以不建立对象的情况下调用类方法吗?

    https://www.cnblogs.com/catch/p/3500678.html在这里看到一个直接使用类初始化调用类方法的。

    静态方法可以通过类来调用,其余得创建对象来调用。那单例模式与一个类全是静态方法在设计角度的差别是什么呢?因为单例模式可以充分的使用面向对象的封装,继承,多态;而一个类所有静态方法不行,在设计角度远不如单态设计灵活。

    展开全文
  • Rational Rose建立对象

    千次阅读 2019-04-18 11:23:41
    确定对象图中有哪些,并浏览器窗口中,建立每个。 步骤: (1)Logic View中添加Person、Company。如图1-20所示。 图1-20 新建Person和Company 2.2建立对象图 步骤: (1)右击LogicalView, ...
  • C++对象数组

    万次阅读 多人点赞 2018-05-14 23:47:15
    //有10个元素的学生类对象数组 2:对象数组的访问形式:数组名[下标].成员名; Eg: asa[j].print(); 3:对象数组的初始化:对象数组的初始化通常也是由构造函数来完成的。 Eg: #include”student.h” int main ...
  • 搜索引擎中,在建立了正排表后需要对正排表按照wordId进行排序,且该排序要保持稳定的特性。因此想到了 python 的列表中存储一个,通过指定的某个属性来进行排序。具体代码如下: 1.首先定义,按照需求...
  • Python中的的定义和对象的创建

    万次阅读 多人点赞 2018-08-16 17:35:59
    面向对象中两个重要的概念: 1.类 :对一类事物的描述,是抽象的、概念上的定义。...1.创建类和创建类对象 1.创建类,类主要由类名,属性,方法组成,当然创建一个类,属性和方法可以选择的。 cla...
  • 一般情况下,编写一个类,是可以在栈或者堆分配空间。但有些时候,你想编写一个只能在...1、静态建立类对象:是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后(编译器)在这片内存
  • 如何限制对象只能建立在堆上或者栈上

    千次阅读 多人点赞 2013-09-25 10:32:57
    在C++中,类的对象建立分为两种,一种是静态建立,如A a;另一种是动态建立,如A* ptr=new A;这两种方式是有区别的。  静态建立一个类对象,是由编译器为对象... 动态建立类对象,是使用new运算符将对象建立在堆空间
  •  静态建立一个类对象,就是由编译器为对象在栈空间中分配内存。使用这种方法,是直接调用类的构造函数。 (2)动态建立,例如 A* p = new A();  动态建立一个类对象,就是使用new运算符为对象在堆空间中分配内存。...
  • 创建派生类对象,构造函数的执行顺序

    万次阅读 多人点赞 2019-04-24 22:04:10
    创建派生类对象,构造函数的执行顺序() 正确答案: A A 基类构造函数,派生类对象成员构造函数,派生类本身的构造函数 B 派生类本身的构造函数,基类构造函数,对象成员构造函数 C 基类构造函数,派生类...
  • Connection对象也称为连接对象,用来创建一个与指定数据源的连接,包括Microsoft SQL server、Oracle以及能够为其指明一个OLEDB提供程序或一个ODBC驱动器的任何数据源。不同的.NET数据提供程序都有自已的连接...
  • 【C++】C++对象、构造函数和析构函数

    千次阅读 多人点赞 2018-06-03 20:32:37
    它即可包含描述事物的数据,又可包含处理这些数据的函数,类在程序运行是被用作样板来建立对象的。所以要建立对象,首先必须定义。 定义 定义一个的一般格式为: class 类名{ private: 成员表1; public:...
  • PHP 对象

    万次阅读 2012-11-23 17:48:03
    封装: 把对象的属性和方法组织一个(逻辑单元)里 继承:以原有的为基础,创建一个新,从而代码复用的目的; 多态:允许将子类类型的指针赋值给父类类型的指针。 --------------------------------
  • 建立对象模型方法

    千次阅读 2010-04-07 19:45:00
    面向对象的分析和设计阶段,致力于建立模拟问题领域的对象模型。建立对象模型即包括自底向上的抽象过程,也包括自顶向下的分解过程 1.自底向上的抽象 建立对象模型的第一步是从问题领域的陈述入手。分析需求的...
  • 1、静态建立类对象:是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数。 2、动态建立类对象...
  • 对象的区别

    万次阅读 2013-03-08 17:24:58
    笔试题之三:对象的区别 对象的抽象,对象的具体实例。 是抽象的,不占用内存,而对象是具体的,占有内存空间。 例如:就是水果,对象就是苹果。 继承与多态 多态性指用一个名字定义不同的...
  • c++一个中嵌套另一个对象

    万次阅读 2018-07-09 22:30:42
    class My2 { public: My2(); ~My2(); }; class My1 { public: My1(); ~My1();...从这里可以看出一个类中嵌套另一个类对象的时候,先执行被嵌套的类的构造函数,执行嵌套函数的构造函数。
  • Pb语言中的对象

    千次阅读 2017-03-26 13:24:24
    对象是相关但不相同的概念。对象是一个的实例,而可以有零个或多个实例。对象(object)是相关函数和...用户PowerBuilder中创建的所有窗口都属于Window。对象的实际物理表示,是用户创建和取消的内容。
  • 在C++中,类的对象建立分为两种,一种是静态建立,如A a;... 静态建立一个类对象,是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函
  • C++中建立类的对象有两种方式: (1)静态建立,例如 A a;  静态建立一个类对象,就是由编译器为对象在栈空间中分配内存。使用这种方法,是直接调用类的构造函数。 (2)动态建立,例如 A* p = new A();  动态...
  • 第一课 认识对象

    千次阅读 2014-11-10 20:41:22
    面向对象的概述 面向过程的思想:强调的是功能和行为。 ...什么是对象对象就是这事物,实实在在存在的个体。 为什么要定义:根据需求,以后的开发其实就是对象, 没有就要创建一个对象
  • C++中对对象基础理解

    千次阅读 多人点赞 2017-03-04 17:41:28
    C++中对对象基础理解 C++不是纯面向对象的编程语言,而是基于面向对象的语言,因为C++中包含C语言的部分,而C语言是...继承:对已有增加属性和功能或进行部分修改来建立新的,是实现代码的复用的重要手段,
  • 【面向对象】包装

    万次阅读 多人点赞 2017-10-24 11:32:07
    包装概念,包装的用途,
  • 昨天一个同学去网易面试C++研发,问到了这么一个问题:如何限制一个类对象栈(堆)上分配空间? 一般情况下,编写一个类,是可以栈或者堆分配空间。但有些时候,你想编写一个只能栈或者只能堆上面分配...
  • 从什么是类开始说起… 我们都知道类也是由成员变量`构造器和方法等构成的 所以其本质也是一个一个的对象 需要通过对象来描述和创建 ...Class类对象无法直接创建 因为它的构造方法是私有的 是由JVM随...
  • JS创建对象

    千次阅读 2018-07-08 17:31:34
    JavaScript 创建类/对象的几种方式JS中,创建对象(Create Object)并不完全是我们时常说的创建类对象,JS中的对象强调的是一种复合类型,JS中创建对象及对对象的访问是极其灵活的。JS对象是一种复合类型,它允许...
  • C++构造函数初始化类对象

    千次阅读 多人点赞 2019-04-12 15:53:51
    在类外构造函数,需要在类内进行声明。 【4】构造函数的名字必须与类名相同。 【5】构造函数通常用于对内的数据进行初始化。 二.构造函数的分类 无参的构造函数 有参的构造函数 参数初始化表的构造函数【重点】...
  • 利用构造函数对类对象进行初始化

    千次阅读 2018-01-27 17:53:00
    1.对象在建立时必须有确定的内容,否则就失去对象的意义了。是一个实体,不能在声明中对数据成员初始化; 2.可以像结构体一样,在定义对象的时候用花括号初始化 3. c++提供了构造函数来处理对象的初始化。构造...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 972,127
精华内容 388,850
关键字:

在建立类的对象时