首页 > 编程语言 >C++面试八股文:什么是构造函数?

C++面试八股文:什么是构造函数?

时间:2023-06-29 23:32:36浏览次数:31  
标签:初始化 Singleton 八股文 int 面试官 C++ Foo 构造函数

某日二师兄参加XXX科技公司的C++工程师开发岗位第29面:

面试官:什么是构造函数?

二师兄:构造函数是一种特殊的成员函数,用于创建和初始化类的对象。构造函数的名称与类的名称相同,并且没有返回类型。构造函数在对象被创建时自动调用。

struct Foo
{
  Foo(int v):val(i){}	//构造函数
private:
  int val;
};

面试官:什么是默认构造函数?什么情况下默认构造函数会被创建?

二师兄:没有任何参数的构造函数(所有参数都要默认参数的构造函数也是)。一般定义类时没有显式的声明任何构造函数,默认构造函数会被编译器自动创建。

struct Foo
{
private:
  int val;
};	//此时默认构造函数会被创建

二师兄:当然就算为类自定义了构造函数,我们也可以通过Foo()=default为类显式定义一个默认构造函数。

面试官:什么是构造函数初始值列表?

二师兄:是为了初始化成员变量所传入的参数列表:

class Foo
{
public:
    Foo(int i, long l):ival_(i),lval_(l){}	//初始值列表
private:
    int ival_;
    long lval_;
};

面试官:上面的构造函数和以下的构造函数有什么区别?

Foo(int i, long l)
{
    ival_ = i;
    lval_ = l;
}

二师兄:这是初始化与赋值的区别。这段代码中的ival_和lval_先被默认初始化,然后被赋值。而初始化列表是直接初始化,少了一步赋值。

面试官:如果把构造函数写成Foo(int i, long l):lval(l),ival_(i){}会有什么问题吗?

二师兄:成员初始化的顺序尽量要和定义的顺序保持一致。如下面的代码,就是未定义的:

class Foo
{
public:
    Foo(int i):jval_(i),ival_(jval_){}	//未定义的行为,因为ival先被初始化,这时候jval是未定义的
private:
    int ival_;
    int jval_;
};

面试官:什么是委托构造函数?

二师兄:构造函数在构造对象的时候把一部分任务委托给其他构造函数进行构造,这是C++11引入的新特性:

class Foo
{
public:
    Foo(int i, long l):ival_(i),lval_(l){}
    Foo(int i):Foo(i,0){}   //委托给Foo(int i, long l)
private:
    int ival_;
    long lval_;
};

面试官:如果构造函数没有初始化任何成员变量,使用这个构造函数会发生什么?

二师兄:成员变量将会被默认初始化

面试官:什么是默认初始化?

二师兄:如果是内置类型(如boolintdouble),将不被初始化,如果是类类型,将执行类类型的的默认构造函数初始化变量。如果类类型的默认构造函数是删除的(=delete)或定义了其他构造函数但是没有定义默认构造函数的,将不能通过编译。

二师兄:类类型的初始化时一个循环的过程,如果类类型中有类类型成员,初始化方式和以上描述的一致。

struct Foo{ int a;}
struct Goo
{
    int b;
    Foo f;
};	
Goo g;	//此g.b是默认初始化,值不确定。Foo中的a也是默认初始化,所以g.f.a的值也是不确定的。

面试官:可以使用virtual修饰构造函数吗?

二师兄:不可以,因为构造函数在对象构造阶段调用,虚表尚未建立,所以无法调用虚函数实现多态。

面试官:可以使用const修饰构造函数吗?

二师兄:不可以,因为构造函数需要初始化成员变量,这与const修饰成员函数的意义相悖。

面试官:可以使用constexpr修饰构造函数吗?

二师兄:可以。这表明类的对象可以在编译器构造。我们所熟悉的std::array的构造函数在C++20下就是constexpr的。

面试官:什么情况下会将一个类的构造函数定义为私有的?

二师兄:一般不希望直接通过类型定义对象,如C++的单例模式:

class Singleton
{
public:
    static Singleton& Instance()
    {
        static Singleton instance;
        return instance;
    }
    Singleton(const Singleton&) = delete;
    Singleton(Singleton&&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    Singleton& operator=(Singleton&&) = delete;
private:
    Singleton() = default;
    ~Singleton() = default;
};

Singleton s; //编译失败
Singleton& s = Singleton::Instance();	//编译成功

面试官:最后一个问题,你知声明、定义、初始化、赋值的区别吗?

二师兄:声明是告诉编译器这里有个符号,但不分配内存。定义告诉编译器,这里有个符号,要分配一块内存给它。初始化时在分配内存的时候给它一个初始值。赋值是将这块内存原来的值擦除,给它填入一个新值。

面试官:好的,今天的面试结束了,请回去等通知吧。

C++类的构造函数的基本考点都在这里了,小伙伴本要理解这些设计及设计背后的取舍,面对面试官的拷问才能对答如流哦。

好了,今天的面试到这里就结束了,让我们期待明天面试官和二师兄的表现吧~

关注我,带你21天“精通”C++!(狗头)

标签:初始化,Singleton,八股文,int,面试官,C++,Foo,构造函数
From: https://blog.51cto.com/binarch/6586682

相关文章

  • C++面试八股文:什么是构造函数?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第29面:面试官:什么是构造函数?二师兄:构造函数是一种特殊的成员函数,用于创建和初始化类的对象。构造函数的名称与类的名称相同,并且没有返回类型。构造函数在对象被创建时自动调用。structFoo{Foo(intv):val(i){} //构造函数......
  • c++实现装饰器模式
    1、构建基本类的抽象#include<iostream>classIComponent{public:virtualvoidOperate()=0;private:};2、构建基本类classComponent:publicIComponent{public:voidOperate()override{std::cout<<"基础操作......
  • C++ 编程中的核心知识点!
    const作用修饰变量,说明该变量不可以被改变;修饰指针,分为指向常量的指针(pointertoconst)和自身是常量的指针(常量指针,constpointer);修饰引用,指向常量的引用(referencetoconst),用于形参类型,即避免了拷贝,又避免了函数对值的修改;修饰成员函数,说明该成员函数内不能修改成员......
  • C++面试八股文:用过STL吗?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第21面:面试官:用过STL吗?二师兄:(每天都用好吗。。)用过一些。面试官:你知道STL是什么?二师兄:STL是指标准模板库(StandardTemplateLibrary),是C++区别于C语言的特征之一。面试官:那你知道STL的六大部件是什么?二师兄:分别是容......
  • C++面试八股文:知道std::unordered_set/std::unordered_map吗?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第27面:面试官:知道std::unordered_set/std::unordered_map吗?二师兄:知道。两者都是C++11引入的新容器,和std::set和std::map功能类似,key唯一,unordered_map的value可变。二师兄:不同于set/map,unordered_set/unordered_map都是无序容器......
  • C#C++联合debug-vs2019
    转自:https://blog.csdn.net/qq_41375318/article/details/127717701vs2019中C#和c++的dll进行联合调试*Major*已于2022-11-0617:29:51修改462收藏2文章标签:c#版权vs2019中C#和c++的dll进行联合调试一C++这边属性的输出目录设置为C#的Debug目录二调试设为C#的exe路径......
  • 为什么在 C++ 中,类的静态成员变量需要在源文件中进行定义?
    为什么在C++中,类的静态成员变量需要在源文件中进行定义?类的静态成员变量需要在源文件中进行定义,以便在链接阶段能够正确地分配内存并为其分配地址。当你在类的头文件中声明一个静态成员变量时,这只是告诉编译器该变量存在,并将在某处定义。这是因为头文件通常被包含在多个源文件......
  • C++类和对象下
    再谈构造函数构造函数体赋值在实例化对象时,编译器会通过调用构造函数给对象中的各个成员变量一个合适的初始值:classDate{public: //构造函数 Date(intyear=2023,intmonth=6,intday=5) { //_year可以多次赋值 _year=year;_year=2024; _m......
  • C++ 相关系数的计算以及在图像配准领域应用演示
    相关系数(皮尔逊相关系数)公式如下 #include<iostream>#include<vector>#include<cmath>usingnamespacestd;//计算平均值doublemean(vector<double>v){doublesum=0;for(inti=0;i<v.size();i++){sum+=v[i];......
  • C++学习---qt的公有类、私有类、Q_Q、Q_D、二进制兼容
    1、二进制兼容如果程序从一个以前版本的库动态链接到新版本的库之后,能够继续正常运行,而不需要重新编译,那么我们就说这个库是二进制兼容的。如果不能保证库的二进制兼容性,就意味着每次发布库的新版本时,依赖该库的所有程序都必须重新编译才能正常运行。2、公有类、私有类是解决......