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

面试官:C++中,设计一个类要注意哪些东西?

二师兄:设计一个类主要考虑以下几个方面:1.面向对象的封装、继承及多态。2.big three或者big five。3.运算符和函数重载、静态成员、友元、异常处理等相关问题。

面试官:请介绍一下面向对象的三个特性。

二师兄:封装是将类的函数和数据封装起来,外部不能直接访问类的数据,而是需要通过方法访问数据。继承是指一个类可以继承另一个类的属性和方法。多态是指一个对象可以表现出多种形态。

面试官:请问多态是如何实现的?

二师兄:多态的是通过父类的指针或引用指向子类的对象实现的。在对象中维护一个虚指针(vtptr),这个指针指向一个虚表(vtable),当用户通过父类对象访问子类的方法时,通过查询虚表中对应的方法的地址,并跳转到此地址执行间接访问对象的方法。所以多态是有一点点运行时开销的。

面试官:你刚才所说的big threebig five是什么?

二师兄:(嘿嘿,被装到了)类的big three分别是拷贝构造函数(copy constructor)、拷贝赋值运算符(copy assignment)和析构函数。而类的big five则多了两个,分别是移动构造函数(move constructor)和移动赋值运算符(move assignment)。后面两个是C++11之后引入的。

面试官:好的。那你知道为什么要引入移动构造和移动赋值吗?

二师兄:主要是为了效率。移动构造和移动赋值不需要把所有的数据重新拷贝一遍,而是霸占了被移动对象的数据的所有权。代价是被移动对象在被移动后不能使用。

面试官:嗯。那你知道为什么移动构造和移动赋值都要加上noexcept关键字吗?

二师兄:额。。。好像不让抛异常?

面试官:你知道类的静态成员变量需要注意哪些问题吗?

二师兄:要注意哪些问题?额。。。

面试官:在成员方法后加const是为什么?

二师兄:主要是为了约束这个成员方法不更改对象的任何数据。

面试官:还有其他的原因吗?

二师兄:好像没有了吧。。。

面试官:类的成员方法可以通过const符号重载吗?

二师兄:这个,,应该可以吧。。

面试官:你知道什么是类的成员方法的引用限定符吗?

二师兄:没有听说过耶。。。

面试官:好的,回去等通知吧。

让我们来看一看今日二师兄的表现吧,

为什么移动构造和移动赋值都要加上noexcept关键字?

因为在使用移动语义时,通常会将资源的所有权从一个对象转移到另一个对象,而不是复制资源。如果抛出异常,那么在转移资源的过程中可能会出现问题,导致资源泄漏或其他不可预测的行为。

另外,加上 noexcept 关键字还可以提高代码的性能,因为编译器可以在不必要的情况下进行优化。

类的静态成员变量需要注意哪些问题?

静态成员变量的初始化顺序是不确定的。如果一个静态成员变量依赖于另一个静态成员变量的值,要确保第二个静态化成员先被初始化,否则程序可能会出现未定义的行为。

静态成员变量的值可以被多个实例同时修改,因此在多线程访问静态成员时要注意数据竞争问题。静态变量的生命周期与程序的生命周期相同,因此它们可能会占用大量的内存。

在成员方法后加const是为什么?

一是可以约束此方法不会更改对象的任何数据。二是cosnt对象也可以访问此成员方法。

#include <iostream>
struct Foo
{
void f1(){std::cout <<"f1" << std::endl;}
void f2() const{std::cout <<"f2" << std::endl;}
};
int main(int argc, char const *argv[])
{
Foo foo;
foo.f1();
foo.f2();
const Foo& foo2 = foo;
foo2.f1(); //这里无法通过编译,因为const对象无法访问非const 方法
foo2.f2(); //这里可以通过编译
}

类的成员方法可以通过const符号重载吗?

这是一个很好的问题,估计很多人没有思考过。先说答案,底层const可以,而顶层const不可以。

#include <iostream>
struct Foo{};
struct Goo
{
void f1(Foo& f){std::cout <<"non const function" << std::endl;}
void f1(const Foo& f){std::cout <<"const function" << std::endl;}
};
int main(int argc, char const *argv[])
{
Foo foo;
Goo goo;
goo.f1(foo); //无法通过编译,error: ‘void Goo::f1(Foo)’ cannot be overloaded with ‘void Goo::f1(Foo)’
return 0;
}

当我们把顶层const改为底层const

#include <iostream>
struct Foo{};
struct Goo
{
void f1(Foo& f){std::cout <<"non const function" << std::endl;}
void f1(const Foo& f){std::cout <<"const function" << std::endl;}
};
int main(int argc, char const *argv[])
{
Foo non_const_foo;
const Foo const_foo;
Goo goo;
goo.f1(non_const_foo); //可以通过编译 non const function
goo.f1(const_foo); //可以通过编译 const function
return 0;
}

那么我们能否通过在函数括号后加上const来重载函数呢?

#include <iostream>
struct Goo
{
void f1() {std::cout <<"non const function" << std::endl;}
void f1() const{std::cout <<"const function" << std::endl;}
};
int main(int argc, char const *argv[])
{
Goo non_const_goo;
const Goo const_goo;
non_const_goo.f1();
const_goo.f1();
return 0;
}

答案是肯定的,因为const_goo.f1() 可以等同于f1(const Goo* goo),也是底层const

最后一个问题虽然简单,但我相信至少有80%的C++程序员不知道是什么,

什么是类的成员方法的引用限定符吗?

类的成员方法的引用限定符是 C++11 中引入的一种新特性,用于指定成员方法的参数是左值引用还是右值引用。

#include <iostream>
struct Foo
{
void f1() & {std::cout << "only left reference can call this function" << std::endl;}
void f1() && {std::cout << "only right reference can call this function" << std::endl;}
};
int main(int argc, char const *argv[])
{
Foo foo;
foo.f1(); //left reference
Foo().f1(); //right reference
return 0;
}

好了,今日份面试到这里就结束了,小伙伴们,对于今天二师兄的面试,能打几分呢?如果是你,以上的问题都能回答的上来吗?

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

C++面试八股文:C++中,设计一个类要注意哪些东西?的更多相关文章

  1. C++中如何设计一个类只能在堆或者栈上创建对象,面试题

    设计一个类,该类只能在堆上创建对象 将类的构造函数私有,拷贝构造声明成私有.防止别人调用拷贝在栈上生成对象. 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建 注意 在堆和栈上创建对象都会调 ...

  2. 第五十九届冠军(使用C++设计一个类不能被继承)

    称号:使用C++设计一个类不能被继承. 分析:这是Adobe 公司2007 的笔试题最新校园招聘. 应聘者的C++基本功底外,还能考察反应能力,是一道非常好的题目. 分析:C++中父类的构造函数会调用 ...

  3. C# 中利用反射机制拷贝类的字段和属性(拷贝一个类对象的所有东西付给另一个类对象,而不是付给引用地址)

    from:https://blog.csdn.net/poxiaohai2011/article/details/27555951 //C# 中利用反射机制拷贝类的字段和属性(拷贝一个类对象的所有东西 ...

  4. Java项目中每一个类都可以有一个main方法

    Java项目中每一个类都可以有一个main方法,但只有一个main方法会被执行,其他main方法可以对类进行单元测试. public class StaticTest { public static ...

  5. C++ //多继承语法 C++中允许一个类继承多个类

    1 //多继承语法 C++中允许一个类继承多个类 2 #include <iostream> 3 #include <string> 4 using namespace std ...

  6. 阿里P8面试官:如何设计一个扛住千万级并发的架构?

    大家先思考一个问题,这也是在面试过程中经常遇到的问题. 如果你们公司现在的产品能够支持10W用户访问,你们老板突然和你说,融到钱了,会大量投放广告,预计在1个月后用户量会达到1000W,如果这个任务交 ...

  7. 高并发架构系列:如何从0到1设计一个类Dubbo的RPC框架

    在过去持续分享的几十期阿里Java面试题中,几乎每次都会问到Dubbo相关问题,比如:“如何从0到1设计一个Dubbo的RPC框架”,这个问题主要考察以下几个方面: 你对RPC框架的底层原理掌握程度. ...

  8. Java中的一个类怎么调用另一个类中的方法

    如果另一个类中的那个方法是私有的话,就不能直接调用到,如果是其他类型的话看情况,如果是静态的(static)话,直接用类名可以调用到,如果是非静态的,就需要利用另一个类的实例(也就是用那个类生成的对象 ...

  9. 2.spring源码-BeanPostProcessor后置处理之ApplicationContextAwareProcessor,实现spring容器中某一个类的bean对象在初始化时需要得到Spring容器内容。

    需求:我们的需求是,在spring初始化完毕时,使我们自定义一个类Bird类可以得到spring容器内容. 实现步骤: 1.首先我们来看一下ApplicationContextAwareProcess ...

  10. Java中增强一个类的几种方法

    今天有人问我怎么增强一个类的功能.博客刚好没东西,今天就讲讲增强类. 增强的手段有三种类型: 1.继承或者实现接口:特点是被增强对象不能变,增强的内容不能变. 2.装饰着模式:特点是被增强对象可变,但 ...

随机推荐

  1. 使用requests的session发送请求

    import requests # (1)网址 url = 'https://www.xslou.com/login.php' # (2)输入登录框-->输入密码框-->点击登录找到php ...

  2. 这年头,谁的好友列表还没有躺一个ChatGPT啊?

    你要是说这个,我可不困了 大家好,我最近开始使用一款非常有趣的AI机器人,它叫做ChatGPT.ChatGPT是一款独特的聊天机器人,它可以进行智能对话,回答你的问题,还可以学习你的语言习惯,使得对话 ...

  3. kubernetes核心实战(一)--- namespace

    kubernetes核心实战 1.资源创建方式 命令行创建 yaml文件创建 2.namespace 命名空间(namespace)是Kubernetes提供的组织机制,用于给集群中的任何对象组进行分 ...

  4. 网络框架重构之路plain2.0(c++23 without module) 综述

    最近互联网行业一片哀叹,这是受到三年影响的后遗症,许多的公司也未能挺过寒冬,一些外资也开始撤出市场,因此许多的IT从业人员加入失业的行列,而且由于公司较少导致许多人求职进度缓慢,很不幸本人也是其中之一 ...

  5. Terraform 系列-Terraform 简介

    系列文章 Terraform 系列文章 前言 最近在使用 Terraform 来置备 OCI 的 Always Free Tier, 发现它非常好用.总结学习下:Terraform 的基础知识. 什么 ...

  6. MySQL(七)索引

    索引的数据结构 1 为什么使用索引 索引概述 索引(Index)是帮助MySQL高效获取数据的数据结构.是"排好序的快速查找结构",满足特定的查找算法 索引是在存储引擎中实现的,每 ...

  7. 基于django+ansible+webssh运维自动化管理系统

    基于django+ansible+webssh运维自动化管理系统   前言 最初开发这个基于Django ansible运维自动化管理系统的想法其实从大学时候就已经有了,但是苦于技术原因和没有线上环境 ...

  8. ASP.NET Core设置URLs的几种方法,完美解决.NET 6项目局域网IP地址远程无法访问的问题

    近期在dotnet项目中遇到这样的问题:.net6 运行以后无法通过局域网IP地址远程访问.后查阅官方文档.整理出解决问题的五种方式方法,通过新建一个新的WebApi项目演示如下: 说明 操作系统:U ...

  9. 【LeetCode动态规划#13】买卖股票含冷冻期(状态众多,比较繁琐)、含手续费

    最佳买卖股票时机含冷冻期 力扣题目链接(opens new window) 给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 . 设计一个算法计算出最大利润.在满足以下约束条件下,你可以 ...

  10. shell脚本编程(一)

    c81ba641-5ed7-4ab9-a7c0-e319e0f3890b 初识shell脚本编程 最近项目需求,需要了解下shell脚本编程,所以自己就必须玩玩了= = 初识shell脚本编程,找了几 ...