从一个面试题开始学习C++类基础

  前几天一个朋友参加了一个C++的面试,在面试后,他给我发了一个面试题,然后本屌用仅有的一点C++基础,开始了我的关于类的基础学习。题目大致是以下这样的:有一个类A,在main函数调用完之后,会打印哪些信息。

代码如下:

class A
{
public:
    static int m_iCount;

    A(){++m_iCount;}
    ~A(){--m_iCount; print();}

    void print()
    {
        cout << "m_iCount = " << m_iCount << endl;
    }
};

int A::m_iCount = 0;

A func(A aa)
{
    aa.print();
    return aa;
} 

int main(int argc, char *argv[])
{
    A a1;
    a1.print();

    A a2 = func(a1);
    a2.print(); 

    return 0;
}

首先,我将以上代码运行,发现和我预想中的大不一样,打印的信息明显比我预想的答案多。运行结果如下:

经过一番对比我怀疑问题出在了

A a2 = func(a1);

这行代码上。于是我一边增加代码一边调试,类A中增加了拷贝构造函数和赋值操作符,最终形成了以下的代码:

class A
{
public:
    static int m_iCount;

    A(){++m_iCount;}
    ~A()
    {
        --m_iCount; print();
    }
    A(const A& ca)
    {
        cout << "in const" << endl;
    }
    A& operator = (const A& ca)
    {
        cout << "in operator" << endl;
    } 

    void print()
    {
        cout << "m_iCount = " << m_iCount << endl;
    }
};

int A::m_iCount = 0;

A func(A aa)
{
    cout << "in func" << endl;
    aa.print();
    cout << "out func" << endl;
    return aa;
} 

int main(int argc, char *argv[])
{
    A a1;
    cout << "a1 print start" << endl;
    a1.print();
    cout << "a1 print end" << endl; 

    A a2 = func(a1); //方法一
    //以下两行是方法二
    //A a2;
    //a2 = func(a1);

    cout << "a2 print start" << endl;
    a2.print();
    cout << "a2 print end" << endl;

    return 0;
}

然后我又运行了以上代码,其中有方法一和方法两种调用func函数,发现方法二会多调用一次析构函数,这一点我还是没有搞明白。希望哪位大神能帮我解惑一下。

方法一运行结果如下(划红线的两行结果是在调用完func函数前打印的):

方法二运行结果如下(多调用了一次析构函数,而且为什么是先调用了赋值操作符,然后是连续两次析构):

以上疑惑希望大神能不吝赐教。

时间: 2024-10-14 05:18:25

从一个面试题开始学习C++类基础的相关文章

作为一个新人,怎样学习嵌入式Linux?

作为一个新人,怎样学习嵌入式Linux?被问过太多次,特写这篇文章来回答一下. 在学习嵌入式Linux之前,肯定要有C语言基础.汇编基础有没有无所谓(就那么几条汇编指令,用到了一看就会).C语言要学到什么程度呢?越熟当然越好,不熟的话也要具备基本技能.比如写一个数组排序.输入数字求和什么的.学C语言唯一的方法是多写程序多练习,编译出错没关系,自己去解决:执行出错没关系,自己去分析.以前我是用VC来练习C语言的,经常去尝试着写一些C语言竞赛的题目.它们是纯C.纯数学.纯逻辑的题目,不涉及界面这些东

java学习笔记--类ArrayList和LinkedList的实现

在集合Collection下的List中有两个实现使用的很频繁,一个是ArrayList,另一个是LinkedList,在学习中肯定都会有这样的疑问:什么时候适合使用ArrayList,什么时候用LinkedList?这时,我们就需要了解ArrayList和LinkedList的底层的实现,下面,为了更好的了解它们具体是怎样实现的,我们来写自己的ArrayList 和LinkedList. ArrayList底层是基于数组实现的,数组在内存中是存储在连续的存储单元中,在数据查找的时候比较快,适用

经典面试题回答——学习Java基础的目的

本系列知识解释:相信每一个学习Java的人都是从JavaSE开始的,也就是Java基础开始.但是却并不清楚学习Java基础到底有什么用? 首先我来回答这个问题,学习Java基础是有两个目的: 一.掌握基本的Java语言底层编码方法,同时掌握Java这门语言的编程思想,为了后期学习JavaEE打下基础,要不然在学习JavaEE的时候,连封装,继承,多态都不懂,那就实在是没法说了(相信在传智播客学习过Java基础的同学,这些都不是问题.) 二.在学习完JavaSE和JavaEE后招工作的时候能够答上

ffmpeg学习4--ffmpeg类的简单封装,包含解码和定时录像功能

ffmpeg学习4--ffmpeg类的简单封装,包含解码和定时录像功能 参考网上的资料,简单封装了一下ffmpeg,这里记录一下,其它传感器编码及项目中用到的已经抽离,这里只包含解码和录像部分.这只是个玩具级别的测试.完整测试代码下载:代码下载 ffmpegDeCode.h #pragma once #include "stdafx.h" #include<iostream> using namespace std; extern char *VideoPath; exte

上星期IOS的一个面试题。

美丽说面试题 1,IOS是怎样进行内存管理的,什么是ARC. 2,声明Property时,assign,nonatomic,readonly,retain,copy(各什么意思,括号里没打印出来,我猜得) 3,delegate需要retain吗? 4,什么是designated initlalizer?执行[super init]后会发生什么事? 5,isKindOfClass和isMemberOfClass有什么区别? 6,简述UIViewController的生命周期,比较重要的几个方法分别

Java虚拟机JVM学习04 类的初始化

Java虚拟机JVM学习04 类的初始化 类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值. 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行初始化: 2.在静态代码块中进行初始化. 没有经过显式初始化的静态变量将原有的值. 静态变量的声明语句,以及静态代码块都被看做类的初始化语句,Java虚拟机会按照初始化语句在类文件中的先后顺序来依次执行它们. 类的初始化步骤 1.假如这个类还没有被加载和连接,那就先进行加载和连接. 2.假如类存在直接的

面向对象学习【类-匿名类】

匿名类是就就像这个词一样,是一个没有名字的类,看到这个匿名类有点迷糊了,如果大家想想一个类没有名称的话那么我们如何来使用他创建实例呢?答案就是我们可以使用 var 来声明一个匿名的类,创建的格式为: new anonymousClassName{字段1,字段2,........} 说明: 匿名类当中的字段都全部都是public类型的,这就意味着我们可以在外部随意有访问这个所谓的匿名类: 看着这么爽其实这个匿名类还有很多的限制如: 1.使用匿名类时,必须对其初始化: 2.只能包含public字段;

面向对象学习【类-静态类】

静态类只能包含静态成员(使用该类创建的所有对象将共享这些成员的同一个副本).静态类纯粹作为工具方法和字段的一个容器来使用.静态类不能包含任何实例数据或方法.另外,使用new操作符来创建静态类的一个对象是没有意义的.如果坚持这样做,编译器会报错.如果需要执行任何初始化,那么static类可以包含一个默认的构造器,前提是该构造器也被声明为static.其他任何类型的构造器都是非法的,编译器会报错: 比如自己定义一个Math类,其中只包含静态成员,那么应该像下面这样写: public static c

学习C++ -&gt; 类(Classes)的定义与实现

一."类" 的介绍 在C++中, 用 "类" 来描述 "对象", 所谓的"对象"是指现实世界中的一切事物.那么类就可以看做是对相似事物的抽象, 找到这些不同事物间的共同点, 如自行车和摩托车, 首先他们都属于"对象", 并且具有一定得相同点, 和一些不同点, 相同点如他们都有质量.都有两个轮子, 都是属于交通工具等."都有质量"."两个轮子"属于这个对象的属性, 而&