精华内容
下载资源
问答
  • VirtualXposed

    2018-12-26 11:15:47
    VirtualXposed框架虚拟机是基于VirtualApp和epic在非ROOT环境下运行Xposed模块的实现
  • The paper introduces a method of autonomous virtual hand behavior construction in virtual manufacturing environment. The purpose of this research is to realize an intelligent and efficient virtual ...
  • Virtual Box

    2015-04-21 01:46:58
    Virtual Box
  • This paper introduces a method of constructing autonomous virtual hand in virtual assembly environments. The goal of this research is presented to improve the practicability of virtual hand in virtual...
  • C++ Virtual 完美诠释

    万次阅读 多人点赞 2019-03-13 17:37:29
    virtual在英文中表示“虚”、“虚拟”的含义。c++中的关键字“virtual”主要用在两个方面:虚函数与虚基类。下面将分别从这两个方面对virtual进行介绍。1.虚函数 虚函数源于c++中的类继承,是多态的一种。在c++中,...

     

    解答了我的一些疑问,觉得写的不错!!!转载一下。

    virtual在英文中表示“虚”、“虚拟”的含义。c++中的关键字“virtual”主要用在两个方面:虚函数与虚基类。下面将分别从这两个方面对virtual进行介绍。
    1.虚函数

    虚函数源于c++中的类继承,是多态的一种。在c++中,一个基类的指针或者引用可以指向或者引用派生类的对象。同时,派生类可以重写基类中的成员函数。这里“重写”的要求是函数的特征标(包括参数的数目、类型和顺序)以及返回值都必须与基类中的函数一致。如下所示:

    可以在基类中将被重写的成员函数设置为虚函数,其含义是:当通过基类的指针或者引用调用该成员函数时,将根据指针指向的对象类型确定调用的函数,而非指针的类型。如下,是未将test()函数设置为虚函数前的执行结果:

    在将test()函数设置为virtual后,执行结果如下:

    如此,便可以将基类与派生类的同名方法区分开,实现多态。

    说明:

    1.只需将基类中的成员函数声明为虚函数即可,派生类中重写的virtual函数自动成为虚函数;

    2.基类中的析构函数必须为虚函数,否则会出现对象释放错误。以上例说明,如果不将基类的析构函数声明为virtual,那么在调用delete p2;语句时将调用基类的析构函数,而不是应当调用的派生类的析构函数,从而出现对象释放错误的问题。

    3.虚函数的使用将导致类对象占用更大的内存空间。对这一点的解释涉及到虚函数调用的原理:编译器给每一个包括虚函数的对象添加了一个隐藏成员:指向虚函数表的指针。虚函数表(virtual function table)包含了虚函数的地址,由所有虚函数对象共享。当派生类重新定义虚函数时,则将该函数的地址添加到虚函数表中。无论一个类对象中定义了多少个虚函数,虚函数指针只有一个。相应地,每个对象在内存中的大小要比没有虚函数时大4个字节(32位主机,不包括虚析构函数)。如下:

        cout<<sizeof(base)<<endl;                        //12
        cout<<sizeof(inheriter)<<endl;                   //12

    base类中包括了两个整型的成员变量,各占4个字节大小,再加上一个虚函数指针,共计占12个字节;inheriter类继承了base类的两个成员变量以及虚函数表指针,因此大小与基类一致。如果inheriter多重继承自另外一个也包括了虚函数的基类,那么隐藏成员就包括了两个虚函数表指针。

    4.重写函数的特征标必须与基类函数一致,否则将覆盖基类函数;

    5.重写不同于重载。我对重载的理解是:同一个类,内部的同名函数具有不同的参数列表称为重载;重写则是派生类对基类同名函数的“本地改造”,要求函数特征标完全相同。当然,返回值类型不一定相同(可能会出现返回类型协变的特殊情况)。
    2.虚基类

    在c++中,派生类可以继承多个基类。问题在于:如果这多个基类又是继承自同一个基类时,那么派生类是不是需要多次继承这“同一个基类”中的内容?虚基类可以解决这个问题。

    简而言之,虚基类可以使得从多个类(它们继承自一个类)中派生出的对象只继承一个对象。虚继承的写法如下:

    base称为mytest类的虚基类。假设base还是另外一个类mytest2的虚基类,对于多重继承mytest和mytest2的子类mytest3而言,base的部分只继承了一次。如下:

     
         
        cout<<sizeof(mytest)<<endl;                  //输出12
        cout<<sizeof(mytest2)<<endl;                 //输出12
        cout<<sizeof(mytest3)<<endl;                 //输出16,若在base中添加一个int型成员,则输出20

    mytest类与mytest2类的大小为什么是12?这是因为它们在虚继承自base类后,添加了一个隐藏的成员——指向虚基类的指针,占4个字节。而base类本身占8个字节,因此它们的大小均为12。而对非虚继承而言,是不需要这样的一个指针的。而mytest3类的大小为sizeof(base)+sizeof(mytest-base)+sizeof(mytest2-base),即16。

    说明:

    1.若一个类多重继承自具有同一个基类的派生类时,调用同名成员函数时会出现二义性。为了解决这个问题,可以通过作用域解析运算符澄清,或者在类中进行重新定义;

    2.继承关系可能是非常繁复的。一个类可能多重继承自别的类,而它的父类也可能继承自别的类。当该类从不同的途径继承了两个或者更多的同名函数时,如果没有对类名限定为virtual,将导致二义性。当然,如果使用了虚基类,则不一定会导致二义性。编译器将选择继承路径上“最短”的父类成员函数加以调用。该规则与成员函数的访问控制权限并不矛盾。也就是说,不能因为具有更高调用优先级的成员函数的访问控制权限是"private",而转而去调用public型的较低优先级的同名成员函数。
    3.纯虚函数

    若一个类的成员函数被声明为纯虚函数,则意味着该类是ABC(Abstract Base Class,抽象基类),即只能被继承,而不能用来声明对象。纯虚函数通常需要在类声明的后面加上关键词“=0”。

    当然,声明为纯虚函数并不意味着在实现文件中不可对其进行定义,只是意味着不可用抽象基类实现一个具体的对象。

    原文连接:https://blog.csdn.net/xbb123456rt/article/details/81986691

    展开全文
  • virtual lab

    2015-08-08 21:39:48
    virtual lab 基础培训教程,声学边界元
  • 注册机注册码 Virtual virtual dj v1.6
  • VirtualApp

    千次阅读 2018-05-15 20:40:52
    VirtualApp
    
    

    转自:http://rk700.github.io/2017/03/15/virtualapp-basic/

    VirtualApp是一个开源的Android App虚拟化引擎,允许在其中创建虚拟空间,并在这个虚拟空间中运行其他应用。通过阅读源码及动态调试,基本了解了其运行原理,在此记录。

    本质

    Android应用隔离是基于Linux系统的多用户机制实现的,即每个应用在安装时被分配了不同的Linux用户uid/gid。而在VirtualApp中,client应用(通过VirtualApp安装的应用)与host应用(即VirtualApp本身)是具有相同用户uid的。

    因此,VirtualApp在运行时,包含以下三部分:

    • Main Process,进程名io.virtualapp,主要负责VirtualApp用户界面及应用管理
    • Server Process,进程名io.virtualapp:x,主要负责系统服务的代理,是通过Content Provider启动的
    • VApp Process,进程名io.virtualapp:p[0-…],作为将来运行client应用的进程,当client应用启动后,其进程名会更新为client应用的包名

    下面是在VirtualApp中运行应用后通过ps命令得到的结果:

    generic_x86:/ ps |grep u0_a60
    u0_a60    2385  1258  996260 54456 SyS_epoll_ 00000000 S io.virtualapp
    u0_a60    2412  1258  980940 48272 SyS_epoll_ 00000000 S io.virtualapp:x
    u0_a60    3705  1258  993632 54472 SyS_epoll_ 00000000 S org.galaxy.simpleapp

    可以看到,以上进程,均是以VirtualApp的用户uid运行的。因此,Android应用隔离此时不再适用,我们可以对client应用进行hook而无需root权限。


    运行流程

    从启动VirtualApp到运行其中的应用,大致流程如下:

    启动host应用

    我们启动VirtualApp,其Application为io.virtualapp.VApp。在attachBaseContext()方法中会调用到com.lody.virtual.client.core.PatchManager#injectInternal,但此时为Main Process,不进行系统服务的替换。

    启动Server Process

    host应用会进行一些初始化,其中就包括获取全部已安装应用,这会调用到com.lody.virtual.client.core.VirtualCore#getAllApps。而这一方法最终会访问com.lody.virtual.server.BinderProvider。由AndroidManifest.xml可知,该provider会运行在新进程io.virtualapp:x中,即Server Process。

    由于在新进程中启动组件,同样会首先创建该应用的Application,因此也会调用到com.lody.virtual.client.core.PatchManager#injectInternal。此时,会进行相应系统服务(ActivityManager和PackageManager)的代理构造和替换。

    启动VApp Process

    点击一个已安装应用,此时会通过替换掉的系统服务访问真实的系统服务(主要是ActivityManager),并在新进程中启动组件com.lody.virtual.client.stub.StubActivity.C0。由AndroidManifest.xml可知,该进程具有后缀:p0。

    同样的,在该Activity组件启动之前会初始化io.virtualapp.VApp,并在com.lody.virtual.client.core.PatchManager#injectInternal中完成系统服务的代理构造和替换。

    启动client应用

    此时,真正的client应用尚未启动,进程io.virtualapp:p0仅仅是作为一个placeholder。StubActivity会从Intent中获取到client应用的相关信息,并修改自身ActivityThread的handler。随后调用startActivity启动client应用。

    由于之前Server Process和VApp Process都已完成了相关系统服务的替换,这里会完成client应用的bindApplication调用、构造client应用的LoadedApk,并通过反射完成真正的Application和Activity的创建。

    最终,client应用便运行在了我们的VApp Process中。


    系统服务的代理和替换

    VirtualApp之所以能够实现虚拟空间,是因为其对许多系统服务进行了代理和替换。因此,这部分便是整个框架的核心。系统服务运行在system_server中,Android应用调用系统服务,是通过Binder机制进行IPC。因此,应用所持有的是系统服务的BinderProxy,通过对这些BinderProxer构造代理并替换,便实现了对系统服务的代理和替换。

    具体地,我们以com.lody.virtual.client.hook.patchs.am.ActivityManagerPatch为例,这个类实现了对ActivityManager服务的代理和替换。

    代理的构造

    可以看到,这个类的注记中包含了大量类名:

    @Patch({StartActivity.class, StartActivityAsCaller.class,
            StartActivityAndWait.class, StartActivityWithConfig.class, StartActivityIntentSender.class,
            StartNextMatchingActivity.class, StartVoiceActivity.class,
            GetIntentSender.class, RegisterReceiver.class, GetContentProvider.class,
            GetContentProviderExternal.class,
            ...

    而这些列出的每一个类,对应于一个方法的hook,例如,com.lody.virtual.client.hook.patchs.am.StartActivity是ActivityManager服务的startActivity方法的hook。这些类均继承自com.lody.virtual.client.hook.base.Hook,包含了方法beforeCall()call()afterCall(),这些方法便是hook的具体内容。

    ActivityManagerPatch在创建时,会调用到其父类的方法com.lody.virtual.client.hook.base.PatchDelegate#onBindHooks。这里会检查上述注记中列出的hook,并对符合条件的hook调用addHook()方法:

            ...
            Class<? extends PatchDelegate> clazz = getClass();
            Patch patch = clazz.getAnnotation(Patch.class);
            int version = Build.VERSION.SDK_INT;
            if (patch != null) {
                Class<?>[] hookTypes = patch.value();
                for (Class<?> hookType : hookTypes) {
                    ApiLimit apiLimit = hookType.getAnnotation(ApiLimit.class);
                    boolean needToAddHook = true;
                    if (apiLimit != null) {
                        int apiStart = apiLimit.start();
                        int apiEnd = apiLimit.end();
                        boolean highThanStart = apiStart == -1 || version > apiStart;
                        boolean lowThanEnd = apiEnd == -1 || version < apiEnd;
                        if (!highThanStart || !lowThanEnd) {
                            needToAddHook = false;
                        }
                    }
                    if (needToAddHook) {
                        addHook(hookType);
                    }
            ...

    addHook()最终会调用到com.lody.virtual.client.hook.base.HookDelegate#addHook,其实质便是将这个hook添加至映射表internalHookTable中:

        public Hook addHook(Hook hook) {
            if (hook != null && !TextUtils.isEmpty(hook.getName())) {
                if (internalHookTable.containsKey(hook.getName())) {
                    VLog.w(TAG, "The Hook(%s, %s) you added has been in existence.", hook.getName(),
                            hook.getClass().getName());
                    return hook;
                }
                internalHookTable.put(hook.getName(), hook);
            }
            return hook;
        }

    internalHookTable维护了所有的hook,以hook的名称(一般就是所hook的方法的名称)作为key。随后,在com.lody.virtual.client.hook.base.HookDelegate.HookHandlerinvoke()方法中,查找表 internalHookTable中是否包含将要执行的方法名;如果有,则依次执行对应hook的beforeCall()call()afterCall()

        private class HookHandler implements InvocationHandler {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Hook hook = getHook(method.getName());
                try {
                    if (hook != null && hook.isEnable()) {
                        if (hook.beforeCall(mBaseInterface, method, args)) {
                            Object res = hook.call(mBaseInterface, method, args);
                            res = hook.afterCall(mBaseInterface, method, args, res);
                            return res;
                        }
                    }
                    return method.invoke(mBaseInterface, args);

    而这里的类HookHandler,就是构造的Java代理的Handler:

        public HookDelegate(T baseInterface, Class<?>... proxyInterfaces) {
            this.mBaseInterface = baseInterface;
            if (baseInterface != null) {
                if (proxyInterfaces == null) {
                    proxyInterfaces = HookUtils.getAllInterface(baseInterface.getClass());
                }
                mProxyInterface = (T) Proxy.newProxyInstance(baseInterface.getClass().getClassLoader(), proxyInterfaces, new HookHandler());

    对于ActivityManagerPatch来说,这里的baseInterface便是原始的BinderProxy:ActivityManagerProxy

        public ActivityManagerPatch() {
            super(new HookDelegate<IInterface>(ActivityManagerNative.getDefault.call()));
        }

    综上,我们根据baseInterface,为其构造了代理mProxyInterface。从而访问mProxyInterface时,便会执行HookHandlerinvoke()方法,进而查找internalHookTable,对设置了hook的方法执行hook。

    系统服务的替换

    如之前所说,对系统服务的替换,是通过对应用所持有的系统服务的BinderProxy进行替换的。以上是构造代理的基本过程,那么如何将应用所持有的BinderProxy替换成我们构造的代理呢?回到ActivityManagerPatch,这个类的inject()方法完成了实际的替换工作:

        @Override
        public void inject() throws Throwable {
            if (ActivityManagerNative.gDefault.type() == IActivityManager.TYPE) {
                ActivityManagerNative.gDefault.set(getHookDelegate().getProxyInterface());
    
            } else if (ActivityManagerNative.gDefault.type() == Singleton.TYPE) {
                Object gDefault = ActivityManagerNative.gDefault.get();
                Singleton.mInstance.set(gDefault, getHookDelegate().getProxyInterface());
            }
            ...

    ActivityManagerNative.gDefault便是应用所持有的原始ActivityManagerProxy对象,通过Java反射,将替换成为getHookDelegate().getProxyInterface()。而替换的内容,便是我们所构造的代理mProxyInterface

    由此,我们完成了对系统服务进行代理和替换的整个过程。随后,在调用系统服务时,便会执行以下操作:

    • 访问BinderProxy的代理,即我们设置了hook的代理
    • 根据hook的具体内容操作,对数据进行处理;需要调用原始系统服务时,访问原始的BinderProxy
    • 真正的系统服务接收到Binder,进行处理并返回

    总结

    通过以上介绍可以看到,VirtualApp在原有系统服务之上构造了代理,进而为其中的应用搭建了一套虚拟环境,应用可以无感知地运行在这其中。更进一步,我们可以设置这套虚拟环境,使其实现应用多开、非侵入式应用hook等高级功能。


    参考资料

    展开全文
  • VirtualXposed_0.18.0.apk

    2020-01-21 11:42:27
    virtualxposed virtualxposed
  • virtuallab使用说明

    2018-08-30 18:34:10
    virtual lab的说明书,详细介绍virtuallab的使用,附带一些例子
  •  整理UVM中的virtual sequence和virtual sequencer。 1. virtual sequencer 特点 1. high-level control of multiple sequencers。在virtual sequencer中包含driver sequencer和virtual sequencer的句柄。 2....

     0. 介绍

      整理UVM中的virtual sequence和virtual sequencer。

     

    1. virtual sequencer

    特点

    1. high-level control of multiple sequencers。在virtual sequencer中包含driver sequencer和virtual sequencer的句柄。

    2. Virtual sequencer that is not attached to a driver 。它不与driver进行item传输,所以不需要建立端口连接。

    3. does not process items。所以virtual sequencer定义的时候没有类型参数。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    // 这是UVM UG中给的例子

    class simple_virtual_sequencer extends uvm_sequencer;

        eth_sequencer eth_seqr;

        cpu_sequencer cpu_seqr;

    // Constructor

    function new(input string name="simple_virtual_sequencer",

        input uvm_component parent=null);

        super.new(name, parent);

    endfunction

    // UVM automation macros for sequencers

    `uvm_component_utils(simple_virtual_sequencer)

    endclass: simple_virtual_sequencer

    从上面的例子中可以看出,在virtual sequencer中只定义sequencer句柄,并不会实例化(申请内存空间)它们,会通过指针传递将一些实例化之后的真正的sequencer的句柄传进来,一般是在connect phase,如下:

    1

    2

    v_sequencer.cpu_seqr = cpu_seqr;

    v_sequencer.eth_seqr = eth_seqr;

     

    2. virtual sequence

    当验证平台中有多个组件需要并行产生激励,为了控制组建件激励同步,可以用virtual sequence。

     

    特点

    1. 与一个virtual sequencer绑定。

    2. 在其中可以定义sequence和virtual sequence,并在其中启动sequence,这些sequence启动的sequencer通过virtual sequencer传递进来。

    3. 不产生item,定义的时候不需要类型参数。

     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    // UVM UG中的virtual sequence的实例

    class simple_virt_seq extends uvm_sequence;

        `uvm_declare_p_sequencer(vsequencer) //自己加的

    ... // Constructor and UVM automation macros

        // A sequence from the cpu sequencer library

        cpu_config_seq conf_seq;

        // A sequence from the ethernet subsequencer library

        eth_large_payload_seq frame_seq;

        // A virtual sequence from this sequencer's library

        random_traffic_virt_seq rand_virt_seq;

        virtual task body();

        // Invoke a sequence in the cpu subsequencer.

            `uvm_do_on(conf_seq, p_sequencer.cpu_seqr)

        // Invoke a sequence in the ethernet subsequencer.

            `uvm_do_on(frame_seq, p_sequencer.eth_seqr)

        // Invoke another virtual sequence in this sequencer.

            `uvm_do(rand_virt_seq)

        endtask : body

    endclass : simple_virt_seq

    p_sequencer就是启动这个virtual sequence的virtual sequencer。

     

    virtual sequence和嵌套sequence的一个区别是,嵌套sequence中的sequence都在同一个sequencer上启动(通过sequencer仲裁决定);而在virtual sequence中的sequence可以在不同sequencer实体上同时启动。

     

    3. 参考例子

     

    下面例子中,向virtual sequencer中传递sequencer句柄的方式有两种,一种直接通过层次化引用传递;另一种通过config_db机制。

     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    class simple_tb extends uvm_env;

        cpu_env_c cpu0; // Reuse a cpu verification component.

        eth_env_c eth0; // Reuse an ethernet verification component.

        simple_virtual_sequencer v_sequencer;

        ... // Constructor and UVM automation macros

        virtual function void build_phase(uvm_phase phase);

            super.build_phase(phase);

            // Configuration: Set the default sequence for the virtual sequencer.

            uvm_config_db#(uvm_object_wrapper)::set(this,

            "v_sequencer.run_phase",

            "default_sequence",

            simple_virt_seq.type_id::get());

            // Build envs with subsequencers.

            cpu0 = cpu_env_c::type_id::create("cpu0"this);

            eth0 = eth_env_c::type_id::create("eth0"this);

            // Build the virtual sequencer.

            v_sequencer =

            simple_virtual_sequencer::type_id::create("v_sequencer",this);

        endfunction : build_phase

        // Connect virtual sequencer to subsequencers.

        function void connect();

            v_sequencer.cpu_seqr = cpu0.master[0].sequencer; // 直接通过指针传递实例化的driver sequencer

            uvm_config_db#(uvm_sequencer)::set(this,”v_sequencer”,

            ”eth_seqr”,eth0.tx_rx_agent.sequencer);// 通过config_db机制传递实例化的driver sequencer

        endfunction : connect

    endclass: simple_tb

    展开全文
  • VirtualApp工程 全新体验,多种优化 特性 高级,高稳定性,修复重建错误等等 本内核仅供开发人员参考,请勿构建成品并发表到任何地方 仅供自行测试使用 如有修改建议欢迎提交PR 本项目为商业版开源,修改可看commit ...
  • DJ打碟 virtual

    2014-04-13 13:01:19
    DJ打碟 virtual
  • Advances in Virtual Reality

    2018-03-30 07:56:00
    Advances in Virtual RealityAdvances in Virtual RealityAdvances in Virtual Reality
  • Virtual Audio Cable 4破解

    2017-11-25 10:07:36
    Virtual Audio Cable 4破解 Virtual Audio Cable 4破解 Virtual Audio Cable 4破解 Virtual Audio Cable 4破解 Virtual Audio Cable 4破解
  • 1.virtual关键字主要是什么作用?c++中的函数调用默认不适用动态绑定。要触发动态绑定,必须满足两个条件:第一,指定为虚函数;第二,通过基类类型的引用或指针调用。由此可见,virtual主要主要是实现动态绑定。 2....
  • virtual 关键字

    千次阅读 2018-10-11 21:56:31
    1 在类方法中使用virtual 2 类继承时使用virtual 3 纯虚函数 4 动态绑定   一 在类方法中使用virtual  如下:A类中的方法display()为虚函数,B类继承A类,并且重写了A类中的display()函数 在调用...

    1 在类方法中使用virtual

    2 类继承时使用virtual

    3 纯虚函数

    4 动态绑定

     

    一  在类方法中使用virtual

     如下:A类中的方法display()为虚函数,B类继承A类,并且重写了A类中的display()函数

    在调用display函数时会根据实例化对象来判定调用那个函数,如下例中会输出B
    如果去掉virtual,则使用dodisplay编译时会默认A下的display函数

    #include<iostream>
    using namespace std;
    
    class A {
    public:     
    	virtual void  display() 
    	{ 
    		cout << "A" << endl;
    	} 
    };
    class B : public A { 
    public:           
    	void  display() 
    	{ 
    		cout << "B" << endl; 
    	} 
    };
    void doDisplay(A *p) { 
    	p->display();
    	delete p;
    }
    
    
    int main()
    {
       doDisplay(new A());
       doDisplay(new B());
       return 0;
    }

    二 类继承时使用virtual

    #include<iostream>
    using namespace std;
    
    class Person{ 
    public:        
    Person()  {
    name = new char[16];
    cout<<"Person构造"<<endl;
    }      
    virtual  ~Person()  {
    delete []name;
    cout<<"Person析构"<<endl;
    } 
    private:         
    char *name;         
    };
    
    class Teacher :virtual public Person{
    public:         
    Teacher(){ 
    cout<<"Teacher构造"<<endl;
     }              
    ~Teacher(){
     cout<<"Teacher析构"<<endl; 
    }
    };
    class Student :virtual public Person{
    public:         
    Student(){
     cout<<"Student构造"<<endl; 
    }              
    ~Student(){ 
    cout<<"Student析构"<<endl;
     }
    };
    class TS : public Teacher,public Student{
    public:             
    TS(){ 
    cout<<"TS构造"<<endl; 
    }                 
    ~TS(){
     cout<<"TS析构"<<ENDL; 
    }
    };
    
    
    int main(int argc,char* argv[]){
    Person *p = new TS();
    delete p;
    return 0;
    }
    
     

    如果不使用虚继承,结果如下:

    使用虚继承,为了防止二义性的的产生(产生编译错误)以及节省存储空间

    https://blog.csdn.net/ring0hx/article/details/1605254

    注意使用虚继承时基类的析构函数前一定要加 virtual,否则使用delete时只会调用基类的析构函数,派生类中的一些存储空间可能得不到释放,导致出现类存泄露,运行代码时会出现中断(具体原因未知)

     https://blog.csdn.net/u014453898/article/details/60402586

    三  纯虚函数 
    C++语言为我们提供了一种语法结构,通过它可以指明,一个虚拟函数只是提供了一个可被子类型改写的接口。但是,它本身并不能通过虚拟机制被调用。这就是纯虚拟函数(pure
    virtual function)。 纯虚拟函数的声明如下所示:
    class Query {
    public:
    // 声明纯虚拟函数
    virtual ostream& print( ostream&=cout ) const = 0;
    // ...
    };
    这里函数声明后面紧跟赋值0。
    包含(或继承)一个或多个纯虚拟函数的类被编译器识别为抽象基类。试图创建一个抽象基类的独立类对象会导致编译时刻错误。(类似地通过虚拟机制调用纯虚拟函数也是错误的例如)
    // Query 声明了纯虚拟函数
    // 所以, 程序员不能创建独立的 Query 类对象
    // ok: NameQuery 中的 Query 子对象
    Query *pq = new NameQuery( "Nostromo" );
    // 错误: new 表达式分配 Query 对象
    Query *pq2 = new Query;
    抽象基类只能作为子对象出现在后续的派生类中。

    四 动态绑定

    定义对象时为什么要加一个&符号?

    加&表示引用。引用的意思就是起个别名,但还在用原来的变量。
    int a=10;
    int &b=a; //b是a的引用,加后对b操作就是对a操作!
    b=20;
    cout<<a<<endl; 结果是 20.
    不加就不是引用。

     

    参考:
    https://blog.csdn.net/jirryzhang/article/details/79392934

    https://blog.csdn.net/weibo1230123/article/details/77837688

     

    展开全文
  • Unable to start the virtual device. VirtualBox cannot start the virtual device.-附件资源
  • 文章目录RabbitMq 虚拟主机 virtual-host ,Springboot 中使用 RabbitMq 虚拟主机 virtual-host1、在RabbitMQ 控制台中创建虚拟主机2、创建一个用户3、把用户分配给虚拟主机4、在Springboot 项目中指定连接时,连接...
  • MFPlugin 参考@Replugin @VirtualApp @VirtualApk 实现一套动态加载框架
  • virtual CD

    2009-01-21 15:35:34
    virtual cd drive for windows
  • learning virtual reality

    2016-01-02 21:55:24
    为了进一步推动虚拟现实行业的发展,Tony Parisi也撰写专门针对虚拟现实开发的入门的书籍——《Learning Virtual Reality》,该书讲解了虚拟现实开发的基础,涵盖桌面PC、移动手机以及基于浏览器的应用。还包括...
  • VirtualWifi配置

    2011-04-04 15:49:33
    VirtualWifi配置VirtualWifi配置VirtualWifi配置
  • VMware Virtual SAN 6.5 管理手册,VMware Virtual SAN 6.5 发行说明,管理 VMware Virtual SAN-virtual-san-65-administration-guide
  • 如题 什么时候需要用到virtual和pure virtual 怎么用 用的时候应该注意什么
  • VirtualTreeView V6.3

    2016-07-24 19:03:26
    本资源中含VirtualTreeView V6.3和V5.5.3全部文件,另加PDF格式的使用说明(810页)。 V6.X Embacadero's RAD Studio XE3 - 10.1 Berlin V5.X Delphi7 - Delphi XE8 (本资源含VirtualTreeView V5.5.3) Virtual ...
  • VirtualXposed_0.20.2.apk

    2021-01-08 08:52:27
    VirtualXposed 是基于VirtualApp 和 epic 在非ROOT环境下运行Xposed模块的实现(支持5.0~10.0)。 与 Xposed 相比,目前 VirtualXposed 有两个限制: 不支持修改系统(可以修改普通APP中对系统API的调用),因此...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 805,727
精华内容 322,290
关键字:

virtual