C++问题汇总

简述

本文主要针对一些C++比较偏门的一些问题总结,以下结果都是经过真机测试,环境为VS2015,32位。

初始化问题1

int *p1 = new int[10];
int *p2 = new int [10] ();

结果,不带括号的未任意值。带括号初始化为0。
原因:
在C++primer(第5版)中关于new的讨论有:
1、new当个对象
new在自由空间分配内存,但其无法为其分配的对象命名,因次是无名的,分配之后返回一个指向该对象的指针。
1
int *pi = new int; // pi指向一个动态分配的,未初始化的无名对象
此new表达式在自由空间构造一个int类型对象,并返回指向该对象的指针。

默认情况下,动态分配的对象是默认初始化的,这意味着内置类型或组合类型的对象的值是无定义的,而类类型对象将用默认构造函数进行初始化。

2、new(多个对象)数组
new分配的对象,不管单个对象还是多个对象的分配,都是默认初始化。但可以对数组进行值初始化,方法就是:在大小之后添加一对空括号。
1
2
int *pia = new int[10]; // 10个未初始化int
int *pia2 = new int10; // 10个值初始化为0的int

enum相关问题

问题描述:
enum string{
x1,
x2,
x3=10,
x4,
x5,
} x;
函数外部访问x等于什么?
(补充)枚举是按照0开始的递增的,x3后按照10递增。
答案:在全局域定义enum,输出x是0,但是在局部域定义enum,输出x是随机数。本质也就和初始化一样,全局变量默认为0,局部则为随机数。

C++多态性

多态性分为编译时多态性和运行时多态性,
编译时多态性通过静态编联完成,例如函数重载,运算符重载;
运行时多态性则是动态编联完成,主要通过虚函数来实现;

函数重载不需要是成员函数,在类外声明或定义的函数同样可以对其进行重载

重载的调用主要根据参数个数,参数类型,参数顺序来确定, 函数重载是忽略返回值的

析构问题

问题描述:
C c;
void main()
{
A*pa=new A();
B b;
static D d;
delete pa;
}

答案:全局对象在调用 main之前初始化, 在退出main之后析构
析构顺序 A B D C。

C++类的内存布局

先给一张C++的内存布局图
这里写图片描述

具体可看博文:https://www.cnblogs.com/sz-leez/p/7119232.html

C++移位运算符出界

先看一道题出自牛客:
以下代码输出什么?

int a =1,b =32 ;
printf("%d,%d",a<<b,1<<32);

A 1,1
B 1,0
C 0,0
D 取决于编译器
正确答案为D,跟编译器优化有关系。可以看博客
https://blog.csdn.net/hgl868/article/details/7058909

C++ const 相关问题

看一道牛客上的题:
以下程序输出是__

#include <iostream> 
using namespace std; 
int main(void) 
{ 
    const int a = 10; 
    int * p = (int *)(&a); 
    *p = 20; 
    cout<<"a = "<<a<<", *p = "<<*p<<endl; 
    return 0; 
} 

A 编译阶段报错运行阶段报错
B a = 10, *p = 10
C a = 20, *p = 20
D a = 10, *p = 20
E a = 20, *p = 10

这道题在牛客上是有争议的,有人说:
因为a 和p都指向相同的内存地址,所以输出的前两个结果是相同的,但为啥相同的内存里的结果不相同么?--这就是常量折叠.
这个”常量折叠”是 就是在编译器进行语法分析的时候,将常量表达式计算求值,并用求得的值来替换表达式,放入常量表。可以算作一种编译优化。
因为编译器在优化的过程中,会把碰见的const全部以内容替换掉(跟宏似的: #define pi 3.1415,用到pi时就用3.1415代替),这个出现在预编译阶段;但是在运行阶段,它的内存里存的东西确实改变了!!!
简单的说就是,当编译器处理const的时候,编译器会将其变成一个立即数
也有人说:
其实这道题真正的答案是不确定的,他与编译器有关,在C++标准中并没有强制规定将一个const 常量转换为一个非const后应该怎么办,这个是交给编译器设计者来决定的,以VS为例子,如果建立的是.c文件,也就是在纯c的环境下编译该代码,输出的结果将会是20 20,但是如果是C++则是10,20。它真正的处理原理如下,a作用域下在C++中所有的常量a在预编译阶段就已经做了类似于宏替换的工作,所以输出的是它的常量值,但是如果你进去调试就会发现变量a的地址与p地址相同,且p指向的地址的内容已经修改为了20,也就是说其实我们对这部分地址的内容已经做出了修改,所以*p输出的是20。但是在纯C的环境下,它并没有类似于宏替换的那一步,所以它输出的就是修改后的值。

我在vs2015下测试答案为D

各种排序算法复杂度图表

这里写图片描述

类中数据初始化 Static / Const

const static数据成员可以在类内初始化 也可以在类外,不能在构造函数中初始化,也不能在构造函数的初始化列表中初始化
static数据成员只能在类外,即类的实现文件中初始化,也不能在构造函数中初始化,不能在构造函数的初始化列表中初始化;
const数据成员只能在构造函数的初始化列表中初始化;
普通数据成员不能在类内初始化,可以在构造函数中初始化,也可以在构造函数的初始化列表中初始化;

如何让类对象只在栈(堆)上分配空间

《More Effective C++》条款27:
https://blog.csdn.net/hxz_qlh/article/details/13135433

猜你喜欢

转载自blog.csdn.net/wjh_init/article/details/80311149