C++常见面试题

C++常见面试题

1.定义一个空类型,里面没有任何成员变量和成员函数。对该类型求sizeof,得到的结果?如果在该类型中添加一个构造函数和析构函数,在对该类型求sizeof,得到的结果又是多少?如果把析构函数标记为虚函数呢?

结果为1,为什么不是0,空类型的实例中不包含任何信息,本来求sizeof应该是0,但是当我们声明类型的实例的时候,它必须在内存中占有一定的空间,否则无法使用这些实例。至于占多少内存,由编译器决定。在VS中每个空类型的实例大小占有一个字节的空间。添加构造函数和析构函数后,该类型的大小还是1,因为调用构造函数和析构函数只需要知道函数的地址即可,而这些函数的地址只与类型有关,而与类型的实例无关,编译器不会因为这两个函数而在实例中添加任何额外的信息。C++编译器一旦发现一个类型中有虚函数,就会为该类型生成一个虚函数表,并在类型的每一个实例中添加一个指向虚函数表的指针。在32位机器上,一个指针占4字节。在64位机器上,占8字节。


2.编译运行下图中的C++代码,结果是什么?(A)编译错误;(B)编译成功,运行时程序崩溃;(C)编译运行正常,输出10。请选择正确答案并分析原因。此题换一个问法就是:“拷贝构造函数的参数为什么必须使用引用类型?”这个问题, 你会怎么回答? 或许你会回答为了减少一次内存拷贝?

class A  
{  
private:  
    int value;  
public:  
    A(int n)  
    {  
        value = n;  
    }  
  
    A(A other)  
    {  
        value = other.value;  
    }  
    void Print()  
    {  
        cout<<value<<endl;  
    }  
};  
  
int main(void)  
{  
    A a = 10;  
    A b = a;  
    b.Print();  
    return 0;  
}  

答案是A,在上面的例子中,拷贝构造函数A(A other)传入的参数就是A的一个实例,由于是传值参数,我们把形参拷贝给实参会调用拷贝构造函数。因为如果允许拷贝构造函数传值,就会在拷贝构造函数内调用拷贝构造函数,就会形成永无休止的递归调用从而导致溢出。要解决这个问题可以将构造函数修改位为A(const A& other),也就是把传值参数该位常量引用。说明拷贝构造函数的参数使用引用类型不是为了减少一次内存拷贝, 而是避免拷贝构造函数无限制的递归下去。

3.数组与指针的联系与区别

#include<iostream>

using namespace std;

int getsize(int data[])
{
	return sizeof(data);
}

int main()
{
	int data1[] = { 1,2,3,4,5 };
	int size1 = sizeof(data1);

	int *data2 = data1;
	int size2 = sizeof(data2);

	int size3 = getsize(data1);

	cout << size1 <<" "<< size2<<" " << size3 << endl;

}

输出:20 4 4

当声明一个数组时,数组的名字也是一个指针,该指针指向数组第一个元素,data1是数组,sizeof(data1)表示数组大小,但data2是指针,sizeof(data2)表示指针大小,为4。在C/C++中数组作为函数的参数传递时,数组会自动退化为同类型的指针,尽管函数getsize的参数为数组,但它会退化为指针,因为size3为4.


猜你喜欢

转载自blog.csdn.net/alatebloomer/article/details/80305939