两道腾讯的面试真题,考验C++对象模型的理解-阿里云开发者社区

开发者社区> y2hr4cjzssnlm> 正文

两道腾讯的面试真题,考验C++对象模型的理解

简介: 两道腾讯的面试真题,考验C++对象模型的理解
+关注继续查看

1、原题如下:

#include <iostream>
 
using namespace std;
 
class Test
{
public:
    static int getA();
    int getB();
    virtual int getC();
    int a;
    static int c;
};
 
int Test::getA()
{
    return 0;
}
 
int Test::getB()
{
    return 0;
}
 
int Test::getC()
{
    return 0;
}
 
int main()
{
    Test *ptr = (Test*)malloc(sizeof(Test));
 
    //下面的几个调用,哪些会出现问题?
    ptr->getA();
    ptr->getB();
    ptr->getC();
    ptr->a;
    ptr->c;
 
    return 0;
}


答案:所有语句都能通过编译,但是运行时,ptr->getC();这条语句会出错,crash。


分析:考察的地方有malloc和虚函数。


虚函数调用会crash,其他正常。因为其他在编译期间可以确定地址。


malloc调用,不会像new一样调用构造函数(free不会调用析构函数),所有虚函数指针都不会分配。


参考文献:《深度探索C++对象模型》



2、原题如下:


以下代码是否完全正确,执行可能得到的结果是____。


A.程序正常运行

B.程序编译错误

C.程序崩溃

D.程序死循环

#include <iostream>
 
using namespace std;
 
class A
{
    int i;
};
 
class B
{
    A *p;
public:
    B(){p = new A;}
    ~B(){delete p;}
};
 
void sayHello(B b)
{
}
 
int main()
{
    B b;
    sayHello(b);
}

答案:C.首先程序中没有编译错误,也没有死循环(程序中没有循环哪里来的死循环)。有些初学者可能会说main函数没有写return 0,main函数不显性的写return,编译器也会帮你做的。当类中存在指针类型的成员变量时赋值和析构要格外注意,这道题的问题就出在类B对象b中的指针p被析构了两次。

分析:当执行完成B b这句话后,在b中就构造了一个类A的指针对象p,当调用sayHello(b)函数时系统将会调用类B的赋值构造函数构造一个类B的实例bStep(为了方便下面的叙述随便起了一个名字)传入到sayHello函数中(问题就出在bStep这个实例中),这里当sayHello执行完成后,之前构造的实例bStep将被析构(执行delete p)。然后程序继续开心的执行,直到执行完main函数后系统将会析构b,当b被析构时将再次执行delete p。这样p就被析构了两遍导致程序崩溃。


我们把代码增加一些输出信息后大家就更容易看了:


#include <iostream>
using namespace std;
class A
{
    int i;
};
class B
{
    A *p;
public:
    B(){ printf("构造\n"); p = new A; }
    ~B(){ printf("析构\n"); delete p; }
    B(const B &b){ printf("拷贝构造\n"); }
};
void sayHello(B b)
{
}
int main()
{
    B b;
    sayHello(b);
}

控制台输出如下(2次构造函数,2次析构函数):


构造


拷贝构造


析构


析构


正确的方法应该把sayHello函数写成这样:


void sayHello(const B& b)

{

}


控制台输出如下(1次构造函数,1次析构函数):


构造


析构


使用引用的方法效率高,没有拷贝构造函数被调用,因为没有新对象被创建。const目的是避免对象被改变。


参考文献:《Effective C++ 第三版》条款20:宁以pass-by-reference-to-const替换pass-by-value


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10053 0
导入其他包,轻松实现跨包调用 | 带你学《Java面向对象编程》之六十八
本节为读者介绍了不同的包之间如何调用其内的类-使用import导入其他包内容。
704 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
10882 0
浅谈python的对象的三大特性之继承
前面我们定义了人的类,并用这个类实例化出两个人jack和lily,查看了它们的内存空间。 现在我们再来看看类中所存在的对向对象编程的三大特性之继承的一些特性。 前面定义了一个人的类,可是我们还知道,人都有属于自己的职业,比如说老师类,医生类,警察类等。
779 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13869 0
标准会话对象——StandardSession
Tomcat使用了一个StandardSession对象用来表示标准的会话结构,用来封装需要存储的状态信息。标准会话对象StandardSession实现了Session、Serializable、HttpSession等几个接口,为什么需要实现这几个接口呢?Session接口定义了tomcat内部用来操作会话的一些方法;Serializable则是序列化接口,实现它是为了方便传输及持久化;HTTPSession是Servlet规范中为会话操作而定义的一些方法,作为一个标准web容器实现它是必然的。
708 0
《JavaScript设计模式》——第2章 写的都是看到的——面向对象编程 2.1两种编程风格——面向过程与面向对象
面向对象编程就是将你的需求抽象成一个对象,然后针对这个对象分析其特征(属性)与动作(方法)。这个对象我们称之为类。面向对象编程思想其中有一个特点就是封装,就是说把你需要的功能放在一个对象里。比如你大学毕业你来公司携带的行李物品没有一件一件拿过来,而是要将他们放在一个旅行箱里,这样不论携带还是管理都会更方便一些。
1265 0
682
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载