C++问题总结(更新中)

问题1:函数返回数组

函数体内部创建的变量都是局部变量,当函数运行结束的时候,都会抛弃,也就是说你只返回了一个temp指针,这个指针确实是你想要的,这没有问题,但是它指向的内容在函数结束也就是return的那一刻之后就已经物是人非了。所以你用这个这个指针去访问的内容也不是你想要的内容了。
解决方法:动态内存分配,就是new和delete的配合使用。在函数里用new关键字创建一个数组,这样这块地址对应的内容就属于你管理了,再也不会在函数结束的时候被回收了,你也就可以通过返回的指针来访问数组了,最后再delete一下。

问题2:sort()方法的使用

c++标准库里的排序函数的使用方法

I)Sort函数包含在头文件为#include <algorithm>的c++标准库中,调用标准库里的排序方法可以不必知道其内部是如何实现的,只要出现我们想要的结果即可!
II)Sort函数有三个参数:
(1)第一个是要排序的数组的起始地址。
(2)第二个是结束的地址(最后一位要排序的地址)
(3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。
Sort函数使用模板:
Sort(start,end,compare)
eg:

bool compare(int a,int b)
{
    return a>b;
}

问题3:关于free

free之后的指针仍然指向原来的堆地址,即仍然可以继续使用,但很危险。因为操作系统已经认为这块内存可以使用,它会毫不考虑的将他分配给其他程序,于是你下次不小心使用到该指针(野指针)时,如果操作系统及时制止了这种行为,报错(非法操作),然后将你的程序杀掉,给你很容易改正错误的机会,这还算比较好的结果!如果操作系统没有制止这种行为,那么产生的后果可就说不准了,说不定整个操作系统会崩溃,那么你再来改正这个错误,就不容易发现,所以会出现未定义的错误。最好free了以后再置空,即令指针 = NULL;,表示本程序已经放弃再使用该指针。 delete 会调动析构函数,free不会。

问题4:野指针

野指针指向一个已删除的对象或未申请访问受限内存区域的指针。与空指针不同,野指针无法通过简单地判断是否为 NULL避免,而只能通过养成良好的编程习惯来尽力减少。对野指针进行操作很容易造成程序错误。需对指针进行初始化。

问题5:构造(析构)函数执行顺序

当派生类中不含对象成员时:
在创建派生类对象时,构造函数的执行顺序是:基类的构造函数 → 派生类的构造函数;
在撤消派生类对象时,析构函数的执行顺序是:派生类的析构函数 → 基类的析构函数。

当派生类中含有对象成员时:
在定义派生类对象时,构造函数的执行顺序:基类的构造函数 → 对象成员的构造函数 → 派生类的构造函数;
在撤消派生类对象时,析构函数的执行顺序:派生类的析构函数 → 对象成员的析构函数 → 基类的析构函数。
对象成员是包含在类中的对象

问题6:新型强制类型转换

static_castdynamic_castconst_castreinterpret_cast
https://www.cnblogs.com/chenyangchun/p/6795923.html

问题7:关于this指针

如果还有一个变量myclass mz,mz的this就是指向mz的指针。 这样就很容易理解this 的类型应该是myclass *,而对其的解引用*this就应该是一个myclass类型的变量。

  1. this指针的用处:
    一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。
    this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。例如,调用date.SetMonth(9) <===> SetMonth(&date, 9),this帮助完成了这一转换 .
    在成员函数内部,我们可以直接使用调用该函数的对象的成员,而无需通过成员访问运算符来做到这一点,因为this所指的正是这个对象。任何对类成员的直接访问都被看成this的隐式使用。
    this的目的总是指向这个对象,所以this是一个常量指针,我们不允许改变this中保存的地址
  2. this指针的使用:
    一种情况就是,在类的非静态成员函数中返回类对象本身的时候,直接使用 return *this;另外一种情况是当参数与成员变量名相同时,如this->n = n (不能写成n = n)。
  3. this指针程序示例:
    this指针是存在于类的成员函数中,指向被调用函数所在的类实例的地址。

问题8:文件模式

  1. 文件模式常量

常量 含义
ios_base::in 打开文件,以便读取
ios_base::out 打开文件,以便写入
ios_base::ate 打开文件,并移到文件尾
ios_base::app 追加到文件尾
ios_base::trunc 如果文件存在,则截短文件
ios_base::binary 二进制文件
eg:

ofstream ofs("C:\\Users\\03\\Desktop\\1.txt",ofstream::app);//追加到文件的后面,不会覆盖原来内容。

问题9:深拷贝浅拷贝

https://blog.csdn.net/qiqi_77_/article/details/79400900
https://blog.csdn.net/caoshangpa/article/details/79226270

问题10:移动构造函数

https://blog.csdn.net/sinat_25394043/article/details/78728504
复制构造是这样的:
在对象被复制后临时对象和复制构造的对象各自占有不同的同样大小的堆内存,就是一个副本。
移动构造是这样的:
就是让这个临时对象它原本控制的内存的空间转移给构造出来的对象,这样就相当于把它移动过去了。
类似文件的“复制” 和“移动”操作。
复制构造和移动构造的差别:
这种情况下,我们觉得这个临时对象完成了复制构造后,就不需要它了,我们就没有必要去首先产生一个副本,然后析构这个临时对象,这样费两遍事,又占用内存空间,所幸将临时对象它的原本的资源直接转给构造的对象即可了。
当临时对象在被复制后,就不再被利用了。我们完全可以把临时对象的资源直接移动,这样就避免了多余的复制构造。
什么时候该触发移动构造呢?
如果临时对象即将消亡,并且它里面的资源是需要被再利用的,这个时候我们就可以触发移动构造。

问题11:右值引用

https://www.cnblogs.com/qicosmos/p/4283455.html
在C++11中所有的值必属于左值将亡值纯右值三者之一。比如,非引用返回的临时变量、运算表达式产生的临时变量、原始字面量和lambda表达式等都是纯右值。而将亡值是C++11新增的、与右值引用相关的表达式,比如,将要被移动的对象、T&&函数返回值、std::move返回值和转换为T&&的类型的转换函数的返回值等
右值是匿名变量,我们也只能通过引用的方式来获取右值.
右值引用接管资源,不用重新创建临时资源再拷贝,提高了程序的执行效率。

问题12:std::move()

参见源码:
原理:
https://www.cnblogs.com/zoneofmine/p/7440577.html

 template <typename T>
    typename remove_reference<T>::type&& move(T&& t)
    {
        return static_cast<typename remove_reference<T>::type&&>(t);
    }

问题13:迭代器范围(左闭右开)

c++的迭代器范围为左闭右开区间,泛型算法以及一些接受迭代器范围的构造函数都是采用的左闭右开区间。
eg:

string s1("hello");
string s2(s1.begin(),s1.begin()+4);  //此时s2 = "hell"而非”hello“

问题14:union 内存对齐

union的sizeof值确定方法:
1.必须放得下union里的任何一个元素或元素集合(如数组)
2.必须是union里最宽基本类型的sizeof值的整数倍。

 union u{
 		A a;
 		B b[3];
 		C c;
 }

sizeof(A)=2;sizeof(B)=3;sizeof(C)=5;
则sizeof(u) = 10
总结:
以最长的(b[3])为基准,对齐最大的类型( C )
https://blog.csdn.net/musiccow/article/details/5817285

问题15:对象所占内存

1.非静态成员变量总和
2.数据对齐处理
3.支持虚函数所带来的负担(虚函数表指针)
空类型对象会开辟内存,所以sizeof不为0.

问题16:字符串与字符数组详解

https://www.cnblogs.com/skullboyer/p/7807543.html

问题17:内存分配

一个由C/C++编译的程序占用的内存分为以下几个部分:
1、栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS(操作系统)回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
4、文字常量区 —常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区—存放函数体的二进制代码。

问题18:编译链接

在这里插入图片描述

问题19:编译过程

在这里插入图片描述

问题20:引用型成员

凡是有引用类型的成员变量的类,不能有缺省构造函数。默认构造函数没有对引用成员提供默认的初始化机制,也因此造成引用未初始化的编译错误。
构造函数的形参必须为引用类型
https://www.cnblogs.com/tangmiao/p/7777008.html

问题21:printf()无输出

printf("s_addr:%d",(servaddr.sin_addr.s_addr));

原因: printf()是带缓冲的,此时内容在缓冲区没有输出到标准输出。
解决方法: 加入“\n”将缓冲区数据刷到输出设备。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章