精华内容
下载资源
问答
  • 在构造函数不能调用shared_from_this() 又一次调到坑里,mark一下

    在构造函数里不能调用shared_from_this()

    又一次掉到坑里,mark一下

    展开全文
  • 箭头函数为什么不能作为构造函数

    千次阅读 多人点赞 2020-04-04 22:47:03
    这是常见面试题,我就按照我的理解回答常见答案:写法更简洁,没有this指向,this来自上下文,不作为构造函数,这时候面试官追问,为什么箭头函数不能作为构造函数? 我之前对于这个问题的理解是,构造函数需要...

    在电话面试中,被问到箭头函数和普通函数的区别。这是常见面试题,我就按照我的理解回答常见答案:写法更简洁,没有this指向,this来自上下文,不能作为构造函数,这时候面试官追问,为什么箭头函数不能作为构造函数?

    我之前对于这个问题的理解是,构造函数需要this这个对象,用于接收传来的参数,以及在构造函数最后将这个this return出去。箭头函数没有this,所以不能作为构造函数。

    由于紧张,我的回答逻辑比较混乱,当然答案也不完全对,所以答的很不好,面试官对我的回答不太满意。继续追问,**那箭头函数能被new么?**不能作为构造函数肯定不能new啊,但我当时有点懵,想了一下才回答,应该不能吧。。。面试官看我犹豫,继续追问,那箭头函数有原型函数么?

    其实整个过程面试官都是在引导我,但我由于当天面试状态特别差(也是第一次收到沟通电话同时就开始面试的),所以整个交流过程语无伦次,紧张异常,所以回答特别差,电话里就知道自己挂了。

    现在回来复盘,打算从这个问题开始引申,将相关概念进行细致理解,概念解释都来自MDN。

    整个问题大致包括以下几个概念:

    1. 箭头函数
    2. 构造函数
    3. new运算符
    4. 原型链

    箭头函数

    **箭头函数表达式**的语法比函数表达式更简洁,并且没有自己的thisargumentssupernew.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

    从mdn的文档中可以看到:

    • 没有单独的this
    • 不绑定arguments
    • 箭头函数不能用作构造器,和 new一起用会抛出错误
    • 箭头函数没有prototype属性
      。。。

    这都是和普通函数或者构造函数的区别,我们可以通过打印箭头函数和构造函数来查看区别。

    function Fun(a) {
        this.a = a;
    }
    
    let fun = (b) => {
        this.b = b;
    }
    
    console.dir(Fun);
    console.log(Fun.a);
    console.dir(fun);
    console.log(fun.b);
    

    构造函数运行结果
    箭头函数运行结果

    • 从上面的运行结果也可以看到箭头函数与构造函数相比,缺少了很多东西,比如:caller,arguments,prototype,但同时也可以看到,箭头函数是有__proto__属性的,所以箭头函数本身是存在原型链的,他也是有自己的构造函数的,但是原型链到箭头函数这一环就停止了,因为它自己没有prototype属性,没法让他的实例的__proto__属性指向,所以箭头函数也就无法作为构造函数。
    • 同时我们可以看到,由于箭头函数没有自己的this指针,通过 call() 或 apply() 方法调用一个函数时,只能传递参数,不能绑定this,所以call()和apply()的第一个参数会被忽略。

    MDN的介绍中的有一句箭头函数表达式更适用于那些本来需要匿名函数的地方,那么

    匿名函数能作为构造函数么?

    这里可以做一个简单的测试代码

    // 定义构造函数
    function Fun(a){
        this.a = a
    }
    // 定义匿名函数并赋予变量
    let fun = function(b){
        this.b = b;
    }
    // 对构造函数实例化
    let f1 = new Fun(1);
    let f2 = new fun(2);
    
    // 打印结果
    console.dir(Fun);
    console.dir(f1);
    console.log(f1.a);
    console.dir(fun);
    console.dir(f2);
    console.log(f2.b);
    

    构造函数执行结果
    匿名函数执行结果

    从执行结果可以看出,两个函数结果,除了变量(name,a,b)不同外,函数结构没有任何区别,所以答案是可以

    构造函数和new运算符

    从以上可以看出,构造函数可以说是和new运算符搭配使用的,所以可以通过new运算符的运行过程来看看构造函数

    new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。new 关键字会进行如下的操作:

    1. 创建一个空的简单JavaScript对象(即{});
    2. 链接该对象(即设置该对象的构造函数)到另一个对象 ;
    3. 将步骤1新创建的对象作为this的上下文 ;
    4. 如果该函数没有返回对象,则返回this。
    function Fun(a){
        this.a = a;
    }
    
    let fun = new Fun(1);
    
    {// new的执行过程
    var this = {} //定义一个空的this变量
    this.__proto__ = Fun.prototype //将实例对象的_proto_属性指向构造函数的原型
    Fun(1).call(this) //将实参带入构造函数,并将构造函数this的指向改为创建的this对象。
    return this //返回这个刚创建的this对象,并赋值给fun变量。
    }
    // 一般情况下,构造函数内不写返回值,返回这个this对象,
    // 但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤
    

    由此可以再一次看出,如果箭头函数能作为构造函数,能够使用new运算符,那么整个过程中,无论是this对象,prototype属性还是call()函数进行this绑定都无法处理,所以对箭头函数使用new运算符会抛出Error

    箭头函数有原型函数么?


    这里的原型函数应该就是指构造函数的显示原型属性,或者更准确的说法是箭头函数有它的构造函数么?

    • 所有的引用类型都有__ proto __属性
    • 只有函数对象有prototype属性
    • 所有的引用类型的__ proto __属性值均指向它的构造函数的prototype的属性值
    • 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去他的__ proto __(即它的构造函数的prototype)中寻找

    所以显然箭头函数是有构造函数的,但特别的是,它作为一个函数,它是没有prototype属性的。

    展开全文
  • 在构造函数中调用虚函数

    千次阅读 2019-07-19 15:44:02
    所以在构造函数中完全可以调用虚函数,只是调用的语义不符预期,A()的this类型是A *指针,我们期望调用的是B::fun(),但是实际上调用的是A::fun()。 原因也很简单,仔细过一下构造函数的执行流程即可。调用B...
    #include <iostream>
    using namespace std;
    class A {
    public:
    	A() {
    		this->fun();
    	}
    	virtual void fun() {
    		cout << "A fun" << endl;
    	}
    };
    
    class B :public A {
    public:
    	B() {
    		this->fun();
    	}
    	virtual void fun() {
    		cout << "B fun" << endl;
    	}
    };
    
    int main() {
    	B b;
    
    	return 0;
    }
    

    输出:

    所以在构造函数中完全可以调用虚函数,只是调用的语义不符预期,在A()中的this类型是A *指针,我们期望调用的是B::fun(),但是实际上调用的是A::fun()。

    原因也很简单,仔细过一下构造函数的执行流程即可。调用B的构造函数,先调用A的构造函数,调用A的构造函数,先按照A对象的内存布局进行初始化,因为虚表指针是放在顶部的,先初始化虚表指针,指向虚表(虚表在编译期就生成),之后按照声明顺序初始化成员变量。最后调用构造函数{ }中的代码。由此可见调用this->fun( )时已经设定好虚表指针,所以调用不会有任何问题。之后B将虚表指针指向自己的虚表,初始化自己的成员变量,最后调用B(){ }中的代码this->fun( ),这个时候对象顶部的虚表指针指向B的虚表,调到的自然是B::fun( )。

    析构函数完全相反,先调用析构函数{ }中的代码。

     

     

     

    展开全文
  • 构造函数不能声明为虚函数,析构函数可以声明为虚函数,而且有时是必须声明为虚函数。 构造函数不能声明为虚函数的原因是: 1 构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是运行期间确定实际类型的...

    构造函数不能声明为虚函数,析构函数可以声明为虚函数,而且有时是必须声明为虚函数。
    构造函数不能声明为虚函数的原因是:
    1 构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是在运行期间确定实际类型的。而在构造一个对象时,由于对象还未构造成功。编译器无法知道对象 的实际类型,是该类本身,还是该类的一个派生类,或是更深层次的派生类。无法确定。
    2 虚函数的执行依赖于虚函数表。而虚函数表在构造函数中进行初始化工作,即初始化vptr,让他指向正确的虚函数表。而在构造对象期间,虚函数表还没有被初始化,将无法进行。

    展开全文
  • 今天用C++写与Mysql数据库交互的时候碰到一个问题,代码如下: class Mysql { private: string Host; string User; string Password; string Database; MYSQL* mysql; public: Mysql() { mysql_init...
  • 而虚函数的运行是建立对象的基础上,在构造函数执行时,对象尚未形成,所以不能构造函数定义为虚函数,通常析构函数才会用virtual修饰(虚函数实际存放对象的头部的虚函数表的) ...
  • 使用 this 关键字 public class Flower {  int petalCount = 0;  String s = "cyl is qingliu";  Flower(int petals){  System.out.println("int");  petalCount = petals;  }    ...
  • C++ 不能使用默认构造函数的情况

    千次阅读 2019-05-09 17:34:10
    含有const或引用类型成员变量时编译级别禁止使用默认构造函数,含有指针运行时级别不能默认构造函数。 测试代码(public成员变量仅为测试使用): #include <iostream> using namespace std; class ...
  • JavaScript 构造函数

    千次阅读 多人点赞 2018-11-10 20:08:26
    但是,JavaScript语言的对象体系,不是基于“类”的,而是基于构造函数(constructor)和原型链(prototype)。 以下的内容会分为如下细节: 1.对象的概念 2.构造函数 3.new 命令  3.1:基本原理  3.2:...
  • 构造函数不能是虚函数

    千次阅读 2019-04-30 10:08:53
    如果构造函数是虚的,就需要通过 虚指针执行那个虚函数表(编译期间生成属于类)来调用,可是对象还没有实例化,也就是内存空间还没有,就没有虚指针,所以构造函数不能是虚函数。 2.虚函数的作用在于通过父类的指针...
  • 构造函数中为什么不能调用虚函数? 构造函数调用层次会导致一个有趣的两难选择。试想:如果我们在构造函数中并且调用了虚函数,那么会发生什么现象呢?普通的成员函数,我们可以想象所发生的情况——虚函数的...
  • 题目如下:问下列代码的打印结果为0吗?...所以,实际使用的时候,单纯的在构造函数中调用其它的构造函数,只是会产生一个临时的匿名变量。如果仅仅是为了重用代码,可以把重用的代码封装成一个新的函数。
  • 构造函数与拷贝构造函数

    千次阅读 多人点赞 2019-04-03 09:07:15
    拷贝构造函数和构造函数不能分开说,他们都是初始化对象的一种方法。但是我们这里用构造函数辅助说明拷贝构造函数,主要说说拷贝构造函数的声明,用途和使用注意事项。 众所周知,构造函数是一个初始化类对象的函数...
  • 这个默认构造函数不做任何初始化工作。一旦用户编写了构造函数,则这个无参数的默认构造函数就消失了。如果用户还希望有一个无参数的构造函数,必须自行编写。 构造函数也是一种函数, 所以定义时可以将其定义为...
  • 通过构造函数创建对象吗 A. 是 B. 否 答案:A 解析:Java 创建对象的几种方式(重要): (1) 用 new 语句创建对象,这是最常见的创建对象的方法。 (2) 运用反射手段,调用 java.lang.Class 或者 java.l ang.reflect....
  • C++ 拷贝构造函数和赋值构造函数

    万次阅读 多人点赞 2019-04-06 16:43:35
    C++复制控制是一个比较重要的话题,主要包括复制构造函数、重载赋值操作符、析构函数这三部分,这三个函数是一致的,如果类需要析构函数,则它也需要复制操作符 和 复制构造函数,这个规则被称为 C++的“三法则...
  • 问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,无法找到vtable,所以构造函数不能是虚函数。 ②从使用角度  虚函数主要用于信息不全的情况下,使...
  • C++,提倡不能在构造函数和析构函数调用虚函数。 这是为什么呢?首先,我们先回顾一下C++虚函数的作用。 虚函数的引入是c++运行时多态的体现,通过调用虚函数可以运行程序时实现动态绑定,体现了面向对象...
  • C#从构造函数中调用其他构造函数

    千次阅读 2019-06-22 18:14:42
    有时,一个类有几个构造函数,以容纳某些可选参数,这些构造函数包含一些共同的代码。例如,如下情况: Class Car { private string _description; private int _nWheels; public Car(string ...
  • c++ 构造函数详解

    万次阅读 多人点赞 2019-05-31 17:20:58
    c++构造函数详解。(构造函数的分类、拷贝构造函数
  • Java构造函数中调用构造函数

    千次阅读 2019-07-22 23:44:39
    Java,当为一个类创建了多个构造函数时,有时想一个构造函数中调用另一个构造函数以减少代码量。这时可以使用this关键字来实现。通常,当使用this关键字时,它意味着“这个对象”或者“当前对象”,并且它自身...
  • 首先:到底能不能构造函数声明为虚函数?答案是不能
  • malloc free 是C语言的函数 new delete 是C++的操作符#include ...//构造中调用构造是危险的行为 因为会生成匿名对象 匿名对象会消失 class MyTest { public: MyTest(int a, int b, int c) { this->a = a;
  • C++默认构造函数构造函数初始化列表

    千次阅读 多人点赞 2018-12-13 10:59:45
    (2)默认构造函数:默认构造函数调用时需要显示地传入实参的构造函数。 一个类如果自己没有定义构造函数,则会有一个无参且函数体也是空的默认构造函数。只要程序员定义了构造函数,编译器就不会再提供默认...
  • 构造函数

    千次阅读 2019-07-29 17:47:25
    构造函数 构造函数:方法名和类名相同,没有返回值的类型这个的方法就是构造函数 构造函数的调用是通过new 关键字来调用...如果自己定义了一个带参数的构造函数,则系统的默认无参数构造函数就不会提供...
  • 可以,但是达到想要的效果,应该尽可能避免在构造函数和析构函数调用虚函数。 class base{ public: base(){ cout(); } private: virtual size_t size(){ return sizeof(*this); } }; class
  • C++构造函数概念及使用方法

    千次阅读 多人点赞 2020-07-12 16:31:36
    c++的类构造函数是一种特殊的成员函数,每次创建创建一个类的时候会默认调用构造函数进行初始化工作。 构造函数用来完成一些必要的初始化工作,有了构造函数之后,就无需再单独写初始化函数,并且也不必担心...
  • C++的类——构造函数

    万次阅读 多人点赞 2018-08-29 13:57:31
    一、什么是构造函数 每个类都分别定义了它的对象被初始化的方式,类通过一个或几个特殊的成员函数来控制其对象的初始化过程,这些函数叫构造函数构造函数的任务是初始化类对象的数据成员,无论何时只要类的对象被...
  • C++一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法。 构造函数就是当创建一个类的对象时,它被调用来对类的数据成员进行初始化和分配内存。拷贝构造函数是一种特殊的构造函数,用...
  • JS 中构造函数和普通函数的区别

    万次阅读 多人点赞 2018-10-04 19:03:53
    1、构造函数也是一个普通函数,创建方式和普通函数一样,但构造函数习惯上首字母大写 2、构造函数和普通函数的区别在于:...构造函数的调用方式:需要使用new关键字来调用 new Person(); 4、构造函数的函数名与...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,957,349
精华内容 782,939
关键字:

哪些函数不能在构造函数中使用