精华内容
下载资源
问答
  • 3.2、抽象一个类实例化对象

    千次阅读 2018-03-28 19:20:36
    一、抽象一个类 二、实例化对象 1、实例化对象 2、对象类型在内存中分配情况 三、$this 四、构造函数和析构函数

    一、抽象一个类
    所谓抽象一个类,就是怎么创建一个类。
    1、类的声明
    类的声明只需要使用关键字class,有时候需要在关键字前加上修饰类的关键字,如abstract或者final等,有时候还有Trait等关键字来取代class。声明格式如下:
    【修饰类的关键字】class 类名{
    类中成员
    }
    实例:eg:

    <?php
    class Base {
        public function sayHello() {
            echo 'Hello ';
        }
    }
    

    类名、变量名、函数名的命名规则,需要遵循PHP自定义名称的命名规则。如果由多个单词组成,习惯上每个单词的首字母要大写。
    2、类的成员属性
    类的成员属性声明,需要public,protected,private,static等关键字来修饰
    eg:

    <?php 
    
    class test 
    { 
        public $var1 = 1; 
        protected $var2 = 2; 
        private $var3 = 3; 
        static $var4 = 4; 
    } 
    

    3、类的成员方法
    类的成员方法声明和其属性类似,只是要加关键字function,也要有关键修饰词:public,protected 和 private等。
    eg:

    <?php
    class MyClass
    {
        private $foo = FALSE;
    
        public function __construct()
        {
            $this->$foo = TRUE;
    
            echo($this->$foo);
        }
    }
    

    二、实例化对象
    我们在创建类之后,并不是直接使用类,而是通过类来实例化出对象。
    1、实例化对象
    实例化对象需要使用的new关键字,一个类可以被实例化出多个对象,对象之间没有关联。
    eg:

    <?php
    	class MyClass
    	{
    	    private $foo = FALSE;
    	
    	    public function __construct()
    	    {
    	        $this->foo = TRUE;
    	
    	        echo($this->foo);
    	    }
    	}
    	
    	$bar = new MyClass();
    

    2、对象类型在内存中分配情况
    内存大体上被分为四段:
    1)栈空间段
    该空间段主要特点是:空间小,被访问速度快,后进先出(先进后出)。用于存储占用空间不变且占用空间小的数据类型的内存段。例如整型1、10、10000在内存中占用的空间是等长的,都是32位4字节。整型、double、boolean等类型都可以存储在栈空间段。
    2)堆空间段
    用于存储数据长度不定长,而且占用空间很大的数据类型的数据,例如字符串、数组、对象。该段是动态分配的。
    3)初始化数据段
    用于存放可执行文件中已初始化的全局变量,数据段存储经过初始化的全局和静态变量
    4)代码段
    存放可执行文件的操作指令,就是可执行程序在内存中的镜像。代码段需要防止在运行时被非法修改,所以只允许读取操作,不允许写入(修改)操作。例如程序中的函数就存储在该内存段中。
    其各段特点简要说明如下图:
    这里写图片描述

    实例说明:eg:

    <?php
    	class person{
    		public $name;
    		public $sex;
    		public function say(){
    			echo '666';
    		}
    	}
    	$p1 = new person();
    	$p2 = new person();
    	$p3 = new person();
    	/**$p1是第一个对象的引用变量(通过“=”把第一个对象的首地址"0xff001",赋值给了$p1),
    	 * 存放的是一个十六进制的整数被存放在栈内存中。相当于一个指针指向堆里边的对象。
    	 * 所以访问对象里边的成员都需要通过引用变量$p1
    	 */
    

    上段代码图形说明如下:
    这里写图片描述
    易混淆点:
    1、当将对象赋值给另一个变量时,此时是将对象的“首地址”赋值给了另一个变量,堆内的对象并没有复制一份。
    实例说明eg1:

    <?php
    	class test{
    		public $name;
    	}
    	$a = new test();
    	$b = $a;//这里与$b = &$a效果是一样的,仅针对对象
    	$b->name = 123;
    	var_dump($a->name);//输出123,说明只是将第一个对象的“首地址”赋值给了$b,改变的都是一个堆内的对象属性值
    	unset($a);
    	var_dump($b->name);//输出123,unset释放的只是第一个对象栈中的引用变量。
    	
    

    示例1说明图:
    这里写图片描述
    2、如果想得到一个对象的副本,用$a =clone $b; 用了clone后会产生一个新对象,分配内存,独立于原来的$a。
    eg2:

    <?php
    	class test{
    		public $name;
    	}
    	$a = new test();
    	$b = clone $a;
    	$b->name = 123;
    	var_dump($a->name);//输出null
    	unset($a);
    	var_dump($b->name);//输出123
    

    示例2图形说明:
    这里写图片描述

    3、当一个对象的引用断了的时候,这个对象在堆中就被当做垃圾,php就会执行垃圾回收机制,将这个对象回收,如图
    这里写图片描述
    4、栈内后进先出(先进后出)机制
    eg3:

    <?php
    class test  
    {  
        public $name;  
        //构造函数,当类被实例化时,会自动执行
        public function __construct($name)  
        { 
            $this -> name = $name;  
            echo $this->name."这里被执行了<br>";  
        }  
        public function __destruct()  
        {  
            echo $this->name."我被回收了<br>";  
        }  
    }
    $p1 = new test('王二');
    $p1 = 1;  
    $p2 = new test("张三");  
    $p3 = new test("李四");  
    /**输出 
     * 王二这里被执行了
     * 王二我被回收了
     * 张三这里被执行了 
     * 李四这里被执行了 
     * 李四我被回收了 
     * 张三我被回收了 
     */
    //因为$p1引用被重新赋值,最先失去了引用,所以调用了析构函数。
    //然后在这个脚本执行完成后,开始自动调调用后边对象的析构函数,
    //因为$p2,$p3引用存储在栈内,因为栈内后进先出机制,最后创建的对象最先被释放,所以$p3先被销毁。
    

    三、$this
    在对象的内部,在对象的成员方法中访问自己对象的成员属性,或者对象内的其他成员方法,可以用特殊对象应用this。一旦我们new了一个对象,那么对象中的每个成员方法中都存在一个特殊的对象应用‘this。 一旦我们new了一个对象,那么对象中的每个成员方法中都存在一个特殊的对象应用`thisnewthis。成员方法属于那个对象,那么$this就代表哪个对象。就像你别人要访问你的性别,要用“张三是男生”,但是你自己访问自己的性别,你要用“我是男生”一样。eg3中的例子就用到了$this`。

    四、构造函数和析构函数
    1、构造函数__construct ([ mixed $args [, $... ]] )
    具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
    注意:
    如果子类中定义了构造函数则不会调用其父类的构造函数。
    要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct()。
    如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。

    eg1:

    <?php
    class Base {
       function __construct() {
           print "1";
       }
    }
    
    class Sub extends Base {
       function __construct() {
           parent::__construct();
           print "2";
       }
    }
    
    class OtherSub1 extends Base {
       function __construct() {
           print "2";
       }
    }
    
    class OtherSub2 extends Base {
       
    }
    
    $obj = new Base();//输出1
    $obj = new Sub();//输出12
    $obj = new OtherSub1();//输出2
    $obj = new OtherSub2();//输出1
    

    附:构造函数的参数
    eg:

    <?php
    	class Base {
    		public $name;
    		public function __construct($name = '小王') {
    		   $this->name = $name;
    		}
    		
    		public function name(){
    			echo $this->name;
    		}
    	}
    	$name1 = new Base('小李');
    	$name1->name();//输出‘小李’
    	$name2 = new Base();
    	$name2->name();//输出‘小王’
    

    2、析构函数__destruct ( void )
    析构函数并是不销毁什么,而是会在到某个对象的所有引用都被删除或者当对象被销毁时执行。
    注意
    析构函数没有参数,
    和构造函数一样,父类的析构函数不会被子类中调用,
    要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct()。
    此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。
    析构函数即使在使用 exit() 终止脚本运行时也会被调用。在析构函数中调用 exit() 将会中止其余对象的所有引用都被删除或者当对象被销毁的析构函数的执行。这一点,可以通过实例细细体会。

    展开全文
  • 一个类实例化出一个对象称为单例模式

    一个类只实例化出一个对象称为单例模式

    #include <iostream>
    
    class SingleClass
    {
    public:
        static SingleClass* GetSingleClass()    //静态成员函数
        {
            if (Count > 0)
            //如果Count大于0,那么就调用new创建一个类指针,并且计数Count减1,否则返回NULL
            {
                Count--;
                return new SingleClass();
            }
            else
            {
                return NULL;
            }
        }
    private:
        SingleClass(){};
        static int Count;   //静态成员变量Count,不允许在类中初始化。定义为const则可以在这初始化,但是不可更改,不适合在这使用
    };
    
    int SingleClass::Count = 1; //Count的初始化,可以自己设置限制创建实例的个数
    
    int main()
    {
        SingleClass* test;  //只能通过定义类指针来创建类实例
        test = SingleClass::GetSingleClass();
        return 0;
    }

    #include <iostream>
    
    class SingleClass
    {
    public:
        static SingleClass* GetSingleClass()    //静态成员函数
        {
            if (pSinClass == NULL)
            //如果pSinClass为NULL,那么就调用new创建一个类指针,否则返回NULL
            {
                pSinClass = new SingleClass();
                return pSinClass;
            }
            else
            {
                return NULL;
            }
        }
    private:
        SingleClass(){};
        static SingleClass* pSinClass;   //静态成员变量pSinClass,不允许在类中初始化。定义为const则可以在这初始化,但是不可更改,不适合在这使用
    };
    
    SingleClass* SingleClass::pSinClass = NULL; //pSinClass的初始化
    
    int main()
    {
        SingleClass* test;  //只能通过定义类指针来创建类实例
        test = SingleClass::GetSingleClass();
        return 0;
    }



    展开全文
  • vue如何实例化多个对象

    千次阅读 2019-05-08 06:42:00
    vue可以在js里面实例化多个对象 代码如下 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <link rel="stylesheet" ...

    vue可以在js里面实例化多个对象
    代码如下

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>vue</title>
    	<link rel="stylesheet" href="style.css">
    	<script src="https://cdn.jsdelivr.net/npm/vue"></script>
    
    </head>
    <body>
    	<!--vue-app是根容器-->
    	<h1>初始化多个Vue实例对象</h1>
    	<div id="vue-app-one">
    		<h2>{{title}}</h2>
    		<p>{{greet}}</p>
    	</div>
    
    	<div id="vue-app-two">
    		<h2>{{title}}</h2>
    		<p>{{greet}}</p>
    		<button @click="changeTitle">ChangeTitle</button>
    	</div>
    
    
    
    	<script src="app.js"></script>
    	
    </body>
    </html>
    

    app.js

    //实例化VUE对象
    var one = new Vue({
    
    	el:"#vue-app-one",
    	//仅限于在vue-app容器下
    	data:{
    		title:"app one的内容"
    		
    		},
    	methods:{
    
    	},
    
    	computed:{
    		greet:function(){
    			return "Hello App One";
    		}
    	}
    });
    
    var two = new Vue({
    
    	el:"#vue-app-two",
    	//仅限于在vue-app容器下
    	data:{
    		title:"app two的内容"
    		
    		},
    	methods:{
    		changeTitle:function(){
    			one.title = "已经改名了!"
    		}
    	},
    
    	computed:{
    		greet:function(){
    			return "Hello App Two";
    		}
    	}
    });
    
    two.title = "app two的Title也发生变化了"
    
    
    

    在这里,vue对象被实例化为one 和 two,而且可以通过方法来互相调用属性,相互影响。

    展开全文
  • 这道题的思路是,我只让这个通过一个公有函数实例化对象,即可以将构造函数设置为私有成员函数。include using namespace std;class Single { public: static Single& SingleCreate() { if (m == NULL) { m =...

    其实这是一道面试题。
    这道题的思路是,我只让这个类通过一个公有函数实例化对象,即可以将构造函数设置为私有成员函数。

    include <iostream>
    using namespace std;
    
    class Single
    {
    public:
    
        static Single& SingleCreate()
        {
            if (m == NULL)
            {
                m = new Single();
            }
                return *m;
        }
        ~Single()
        {
            delete m;
        }
    
        Single(const Single &a)
        {
        if (m == NULL)
        {
        m = new Single();
        }
        }
    
    private:
        Single()
        {}
        static  Single *m;
    };
    
    Single* Single::m = NULL;
    
    int main()
    {
        Single a = Single::SingleCreate();
    }

    这是我第一次写出的代码,我本来认为这样就可以了,结果经过我的调试,发现这样写是有问题的。
    这里写图片描述

    通过上面的图片可以看出,我们实例化的a的地址,跟在SingleCreate函数中返回的m的值是不同的,即这个类实例化了两个对象,这样就偏题了。
    经过分析,我们现在来看SingleCreate函数

        static Single& SingleCreate()
        {
            if (m == NULL)
            {
                m = new Single();
            }
                return *m;
        }

    这里retuen 的*m,会自动生成拷贝构造函数,因为return *m是返回一个对象,这里是返回临时变量,自动调用拷贝构造函数,因为我们没有定义拷贝构造函数,所以这里会自动生成一个拷贝构造函数。
    所以达不到只实例化一个对象的目的
    经过上面的分析,经代码优化为

    
    class Single
    {
    public:
    
    
        static Single* SingleCreatePtr()
        {
            if (m == NULL)
            {
                m = new Single();
            }
            return m;
        }
        ~Single()
        {
            delete m;
        }
    
    
    private:
        Single()
        {}
    
        static  Single *m;
    };
    Single* Single::m = NULL;
    int main()
    {
        Single *a = Single::SingleCreatePtr();
    }

    这个时候经过调试,得到下面
    这里写图片描述
    这个时候就得到的是一个对象。因为传指针的实质是在传地址,不会产生临时变量。
    现在已经解决了在返回值时只实例化一个对象的问题
    接下来看第三个问题
    三、构造函数
    接下来我们在main函数中加这么一句话:

    Single *b = a;

    这个时候会发生什么呢?
    对,会实例化出另一个对象,这是因为编译器自动生成了赋值构造函数,就像上面的拷贝构造函数一样,都是编译器自动生成并调用的,那么如何防止这些情况的发生?
    我的方法是在类中只声明不定义拷贝构造函数以及赋值构造函数。

    class Single
    {
    public:
    
        static Single& SingleCreate()
        {
            if (m == NULL)
            {
                m = new Single();
            }
                return *m;
        }
        static Single* SingleCreatePtr()
        {
            if (m == NULL)
            {
                m = new Single();
            }
            return m;
        }
        ~Single()
        {
            delete m;
        }
    
    
    private:
        Single()
        {}
        Single(const Single &a);
        Single& operator = (const Single &a);
        static  Single *m;
    };

    即将拷贝构造函数和赋值运算符重载函数都变成私有的成员函数,在外不可调用,就避免了因为构造函数多实例化对象的情况。
    四、通过静态局部变量

    class Single  
    {  
    private:  
        Single()   //构造函数是私有的  
        {  
        }  
    public:  
        static Single & GetInstance()  
        {  
            static Single instance;   //局部静态变量  
            return instance;  
        }  
    };  
    

    静态局部变量在GetInstance函数中被定义,初始化为0,且静态局部变量存放在内存的全局数据区。函数结束时,静态局部变量不会消失,每次该函数调用 时,也不会为其重新分配空间。它始终驻留在全局数据区,直到程序运行结束。静态局部变量的初始化与全局变量类似.如果不为其显式初始化,则C++自动为其 初始化为0。
    静态局部变量与全局变量共享全局数据区,但静态局部变量只在定义它的函数中可见。
    通过声明静态局部变量,但不进行初始化及赋值,那么编译器自动初始化为0,且永远不会改变,所以只会实例化一个对象。这个方法更加便捷高效。
    但是上面的代码没有考虑类拷贝的问题,大家参照上面的类拷贝问题可以自己把函数加上,然后去试一试,有问题可以留言大家一起解决~

    展开全文
  • 我们首先知道,不同的具有不同的虚函数表,但是如果针对一个类如果实例化多个对象,那么这些对象的虚函数表是共用的吗?首先如果自己去设计内存占用时,从节省内存的角度去考虑的话,我觉得这些实例化后的应该是...
  • 深入理解Java对象的创建过程:的初始化与实例化

    万次阅读 多人点赞 2017-05-18 14:17:45
    在Java中,一个对象可以被使用之前必须要被正确地初始化,这一点是Java规范规定的。...本文试图对JVM执行初始化和实例化的过程做一个详细深入地介绍,以便从Java虚拟机的角度清晰解剖一个Java对象的创建过程。
  • 一个类实例化对象所占空间的大小? 注意不要说的大小,是对象的大小. 首先,的大小是什么?确切的说,只是一个类型定义,它是没有大小可言的。 用sizeof运算符对一个类型名操作,得到的是具有该类型实体...
  • 一个类实例化对象所占空间的大小? 注意不要说的大小,是对象的大小. 首先,的大小是什么?确切的说,只是一个类型定义,它是没有大小可言的。 用sizeof运算符对一个类型名操作,得到的是具有该类型实体...
  • 枚举也是可以多个实例化

    千次阅读 2019-05-05 20:24:43
    枚举是Java5新添加的一种类型,其本质也是一个类,既然是,怎么不会让实例化,不然本身的那几个实例怎么得来的 枚举并非坚不可摧,我们可以通过下面的代码,绕过构造方法newInstance时,对枚举的检查,注意...
  • 我想请教一下,为什么这里能在定义里实例化对象? 这里还列出了另种方式: class Singleton { static Singleton instance =new Singleton(); private Singleton(){} public void print(){ System.out...
  • 实例化一个对象(加载)的执行顺序详解这篇博客将以加载执行顺序为探索的起点,串讲涉及到的Java相关知识,主要是这个流程中JVN内部运行机制的解析。结论Created with Raphaël 2.1.0开始父类静态代码子类静态代码...
  • 对象的抽象,对象的具体实例对象的另种名称。 2)、的定义 ①、成员属性(变量)的定义与使用 成员属性必须 var public protected private 语法: 形式1:var $v1 ; //定义不赋值 形式2:...
  • 上面Car 是我们自己定义的一个类 mycar则先可看作是变量名。 其实也就叫做对象,在C#入门经典一书里称它为命名实例。 书中说对象和的实例的含义相同。 那么怎么完成实例化呢。我们创建一个对象需要对它初始化...
  • vue,js入门(14)实例化多个vue对象

    万次阅读 2018-05-18 14:19:19
    <!... <title></title> ...1.多个对象可以以var命名,容器名跟着el改变即可 2.可以通过第二个vue对象对第一个vue对象的值进行改变 3.可以直接在外面把vue2的值直接改变 ps:写外面的可以不用接任何符号
  • Java使用new和反射实例化内部类对象

    千次阅读 2017-03-07 16:09:25
    java使用new和反射实例化内部类对象 前两天看到一道面试题,是关于内部的知识,觉得很有意思,现对其详细讲解,绝对原创!~ 这道题是这样的: 根据注释填写(1),(2),(3)处的代码 public class Test{ public ...
  • 详解Java对象实例化

    千次阅读 2015-11-06 11:44:08
    Java是一种面向对象的语言。由于具有面向对象特性的语言,Java支持以下基本概念: 态性 继承 封装 抽象 对象 实例 方法 ... - 一个类可以被定义为描述行为的模板/蓝色印花/指
  • C++实现一个类只有一个实例对象

    千次阅读 2015-10-08 20:37:15
    if (0==s) //s为0才调用构造函数,实例化一次成功后,s不再为0,除非将其释放掉,才能开始下实例化 s = new Base(); return s; } private: Base() {} static Base *s; }; Base *Base::s
  • 声明对象实例化对象的区别

    千次阅读 2015-11-04 11:17:20
    声明对象实例化对象的区别
  • 在子类中用override重写父类中用virtual申明的虚方法时,实例化父类调用该方法,执行时调用的是子类中重写的方法;如果子类中用new覆盖父类中用virtual申明的虚方法时,实例化父类调用该方法,执行时调用的是父类中...
  • C++没有C Sharp中的关键字abstract,但是当一个类中有一个多个纯虚函数的时候,这个就自动成为了抽象,即不可以实例化。纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而...
  • 有些面向对象语言提供了的概念,在这些语言中每个对象都是某个特定实例。lua则没有的概念,每个对象只能自定义行为和形态。不过,要在lua中模拟也并不困难。 lua中,面向对象是用元表这个机制来实现。...
  • Class类对象的三种实例化模式

    千次阅读 2019-05-06 20:24:22
    1任何的实例化对象可以通过Object中的getClass()方法获得Class对象: import java.util.Date; public class Class_test1 { public static void main(String[] args) { //第种Class实例化模式,也将是通过...
  • 抽象:在C++中,当一个类中具有一个多个纯虚函数的时候,这个就是抽象,不能进行实例化。 一般来说,具有纯虚函数的,被称为抽象基类,抽象基类是不能创建抽象类型的对象,而是该的派生去进行实例化...
  • C#简单写法如下: public   class   Singleton { ...单例只能有一个实例。 单例必须自己创建自己的唯一实例。 单例必须给所有其它对象提供这一实例
  • C++实例化对象的大小之sizeof()

    千次阅读 2014-10-19 20:02:49
    C++实例化对象的大小之sizeof()
  • 指向的指针和实例化对象

    千次阅读 2018-08-01 21:57:13
    对于student ,定义了一个对象一个指针。 的指针:他是一个内存地址值,他指向内存中存放的对象(包括一些成员变量所赋的值).  对象,他是利用的构造函数在内存中分配一块内存(包括一些成员变量所赋的值)....
  • 模板实例化问题

    千次阅读 2016-12-05 15:43:03
    模板函数在声明的时候, 其实并不存在,函数地址也就无从谈起了,而导出到动态链接库的函数都需要有地址 (动态链接库不能将模板导出,因为没法生成实例) 如果把模板的声明和...原因是模板实例化要分成两
  • JavaScript 对象实例化

    千次阅读 2018-05-02 16:26:10
    参考资料:《JavaScript入门经典》利用内置对象创建直接实例JavaScript有一个内置对象Object,利用它可以创建一个空白的对象。aObject = new Object();添加属性这样,我们就创建了没有任何属性和方法的空白对象。...
  • 类对象实例对象

    千次阅读 2019-05-08 14:19:56
    2.每个对象都是唯一的 3.对象有属性和行为:指其具体的功能和行为 4.对象具有状态:只瞬间对象的各个属性的取值,对象的行为会改变对象自身的状态,即属性的取值。 5.对象分为对象和实例对象两大对象是...
  • 创建(实例化对象的五种方式

    万次阅读 2018-08-28 10:16:52
    Java中创建(实例化对象的五种方式 用new语句创建对象,这是最常见的创建对象的方法。 通过工厂方法返回对象,如:String str = String.valueOf(23); 运用反射手段,调用java.lang.Class或者java.lang....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,290,881
精华内容 516,352
关键字:

一个类可以实例化多个对象吗