C++重要知识点小结---3

时间:2022-05-19 12:18:06

C++重要知识点小结---1:http://www.cnblogs.com/heyonggang/p/3246631.html

C++重要知识点小结---2:http://www.cnblogs.com/heyonggang/p/3253036.html

1.什么是智能指针

智能指针是一个行为类似指针但也提供其他功能的类。

智能指针类实现普通指针行为的类的区别在于:智能指针通常接收指向动态分配对象的指针并负责删除该对象。用户分配对象,但由智能指针类删除它,因此智能指针类需要实现复制控制成员来管理指向共享对象的指针。只有在撤销了指向共享对象的最后一个智能指针后,才能删除该共享对象。使用计数是实现智能指针类最常用的方式。

2.new和delete表达式

    1、动态创建对象的初始化
  1. int  i(1024);
  2. int *pi = new int (1024);
  3. int s(10,'s');
  4. int *ps = new string(10,'s');
    如果提供了初值,new表达式分配到所需要的内存后,用给定的初值初始化该内存空间,如果不提供显示初始值,动态创建的对象与在函数内定义的变量初始化方式相同,对于类类型的对象,用该类的默认构造函数,内置类型的对象则无初始化。
    2、撤销动态创建的对象
    动态创建对象用完后,必须显示地将该对象占用的内存返回给*存储区,delete表达式释放指针指向的地址空间。
    如果指针指向不是new分配的内存地址,则在该指针上使用delete是不合法的。
    3、悬垂指针
    悬垂指针指向曾经存放对象的内存,但该对象已经不再存在了!一旦删除了指针所指向的对象,立即将指针置为0,这样就非常清楚的表明指针不再指向任何对象。
    4、const对象的动态分配和回收
     动态创建const对象必须在创建时初始化,并且已经初始化就不能再修改。
  1. const int *pci = new const int(1023) ;
    5、动态内存的管理容易出错
  • delete指向动态分配内存的指针失败,因而无法将该块内存返还给*存储区,删除动态分配内存失败称为“内存泄漏”
  • 读写已删除的对象,如果删除指针所指向的对象后,将指针置为0值,比如容易检测
  • 对同一内存空间使用两次delete表达式。当两个指针指向同一个动态创建的对象,删除就会发生错误。

3.类成员函数的重载、覆盖和隐藏区别?

答案:

a.成员函数被重载的特征:

(1)相同的范围(在同一个类中);(2)函数名字相同;(3)参数不同;(4)virtual 关键字可有可无。

b.覆盖是指派生类函数覆盖基类函数,特征是:

(1)不同的范围(分别位于派生类与基类);(2)函数名字相同;(3)参数相同;(4)基类函数必须有virtual 关键字。

c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

4.以下代码中的两个sizeof用法有问题吗?[C易]

void UpperCase( char str[] ) // 将 str 中的小写字母转换成大写字母
{
    for( size_t i=0; i<sizeof(str)/sizeof(str[0]); ++i )
        if( 'a'<=str[i] && str[i]<='z' )
            str[i] -= ('a'-'A' );
}
char str[] = "aBcDe";
cout << "str字符长度为: " << sizeof(str)/sizeof(str[0]) << endl;
UpperCase( str );
cout << str << endl;

答:函数内的sizeof有问题。根据语法,sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。函数外的str是一个
静态定义的数组,因此其大小为6,函数内的str实际只是一个指向字符串的指针,没有任何额外的与数组相关的信息,因此siz
eof作用于上只将其当指针看,一个指针为4个字节,因此返回4.

5。C++中的空类,默认产生哪些类成员函数?[C++易]

答:

class Empty
{
public:
Empty(); // 缺省构造函数
Empty( const Empty& ); // 拷贝构造函数
~Empty(); // 析构函数
Empty& operator=( const Empty& ); // 赋值运算符
Empty* operator&(); // 取址运算符
const Empty* operator&() const; // 取址运算符 const
};

6、写一个函数,完成内存之间的拷贝。[考虑问题是否全面]

答:

void* mymemcpy( void *dest, const void *src, size_t count )
{
char* pdest = static_cast<char*>( dest );
const char* psrc = static_cast<const char*>( src );
if( pdest>psrc && pdest<psrc+cout ) 能考虑到这种情况就行了
{
for( size_t i=count-1; i!=-1; --i )
pdest[i] = psrc[i];
}
else
{
for( size_t i=0; i<count; ++i )
pdest[i] = psrc[i];
}
return dest;

7. const有什么用途?

在 c程序中,const的用法主要有定义常量、修饰函数参数、修饰函数返回值等3个用处。

在c++程序中,它还可以修饰函数的定义体,定义类中某个成员为常态函数,即不改变类中的数据成员。

被const修改的东西都要受到强制保护,可以预防意外的变动,能提高程序的健壮性。

8. const与#define相比有什么不同?

它们都可以用来定义常量,但const比#define有更多优点:

(1) const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误(边际效应)。

(2) 在c++中使用const常量而不使用宏常量,即const常量完全取代宏常量。

参考:http://www.cnblogs.com/heyonggang/archive/2012/12/13/2817065.html

9.编写类string的构造函数析构函数赋值函数,已知类String 的原型为:

 class String
{
public:
String(const char *str = NULL); // 普通构造函数
String(const String &other); // 拷贝构造函数
~ String(void); // 析构函数
String & operate =(const String &other); // 赋值函数
private:
char *m_data; // 用于保存字符串
};

请编写String 的上述4 个函数。
答案:

 //普通构造函数
String::String(const char *str)
{
 if(str==NULL)
 {
  m_data = new char[]; // 得分点:对空字符串自动申请存放结束标志'\0'的空
  //加分点:对m_data加NULL 判断
  *m_data = '\0';
 }
 else
 {
  int length = strlen(str);
  m_data = new char[length+]; // 若能加 NULL 判断则更好
  strcpy(m_data, str);
 }
} // String的析构函数
String::~String(void)
{
 delete [] m_data; // 或delete m_data;
} //拷贝构造函数
String::String(const String &other)    // 得分点:输入参数为const型
{
 int length = strlen(other.m_data);
 m_data = new char[length+];     //加分点:对m_data加NULL 判断
 strcpy(m_data, other.m_data);
} //赋值函数
String & String::operator =(const String &other) // 得分点:输入参数为const型
{
 if(this == &other)   //得分点:检查自赋值
  return *this;
 delete [] m_data;     //得分点:释放原有的内存资源
m_data = NULL;
 int length = strlen( other.m_data );
 m_data = new char[length+];  //加分点:对m_data加NULL 判断
 strcpy( m_data, other.m_data );
 return *this;         //得分点:返回本对象的引用
}

剖析:
  能够准确无误地编写出String类的构造函数、拷贝构造函数、赋值函数和析构函数的面试者至少已经具备了C++基本功的60%以上!
  在这个类中包括了指针类成员变量m_data,当类中包括指针类成员变量时,一定要重载其拷贝构造函数、赋值函数和析构函数,这既是对C++程序员的基本要求,也是《Effective C++》中特别强调的条款。

仔细   学习这个类,特别注意加注释的得分点和加分点的意义,这样就具备了60%以上的C++基本功!

10、请说出static和const关键字尽可能多的作用
  解答:
  static关键字至少有下列n个作用:

  (1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;

  (2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;

  (3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;

  (4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;

  (5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

const关键字至少有下列n个作用:

  (1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;

  (2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;

  (3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;

  (4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;

  (5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。例如:

const classA operator*(const classA& a1,const classA& a2);
  operator*的返回结果必须是一个const对象。如果不是,这样的变态代码也不会编译出错:

classA a, b, c;
(a * b) = c; // 对a*b的结果赋值
  操作(a * b) = c显然不符合编程者的初衷,也没有任何意义。

  剖析:
  惊讶吗?小小的static和const居然有这么多功能,我们能回答几个?如果只能回答1~2个,那还真得闭关再好好修炼修炼。
  这个题可以考查面试者对程序设计知识的掌握程度是初级、中级还是比较深入,没有一定的知识广度和深度,不可能对这个问题给出全面的解答。大多数人只能回答出static和const关键字的部分功能。

11.exit()和return语句的区别(C/C++)

(一)exit用于结束正在运行的程序,exit函数将参数是返回给OS。而return是返回函数值并退出函数。

(二)return是语言级别的,它表示了调用堆栈的返回;而exit是系统调用级别的,它表示了一个进程的结束。

(三)在main函数(其代表一个进程)结束时会隐式地调用exit函数。exit是结束一个进程,它将删除进程使用的内存空间,同时把错误信息返回父进程。所以一般程序执行到 main() 的结尾就完成了, 如果想要随时结束程序,可以尝试着用这个exit函数。

(四)void exit(int status);一般status是:0 为正常退出;非0为非正常退出

12.C/C++中容易混淆的运算符

(一)取地址运算符&
运算对象数目:只有一个
运算结果:该运算对象所在内存空间起始地址
例如:
    int
m=3;
 
  cout<<&m<<endl;

(二)指针运算符*
运算对象数目:只有一个(该运算对象必须是指针型变量)
运算结果:该运算对象的指针所指向的变量

例如:

int
a=8;

int
*m=&a;

cout<<*m<<endl;

(其中的*m就是a)

(三)域运算符.
运算对象数目:有2个(该运算对象必须是结构体变量和该结构体变量的成员变量)
运算结果:该结构体变量的成员变量

例如:

struct Node{

int data;

};

int main(){

int
a=1;

Node
head;

head.data=a;

cout<<head.data<<endl;

}

(四)链接运算符->
运算对象数目:有2个(该运算对象必须是结构体变量和该结构体变量的成员指针型变量)
运算结果:该结构体变量的成员指针型变量所指向的变量

例如:

struct
Node{
       
 int data;
       
 struct Node *next;
    };
    int
main(){
      
 int a=1;
      
 Node head,L;
      
 head.next=&L;
      
 L.data=a;
      
 cout<<head.next->data<<endl;

cout<<(*head.next).data<<endl;

}
(->相当于(*).)

13. exit(0) , exit(1) , exit(-1)

exit(0) 表示程序正常退出
exit(1)/exit(-1)表示程序异常退出,至于是1还是-1个人习惯,但是正常情况下应该用
EXIT_SUCCESS表示正常,EXIT_FAILURE表示失败,定义在stdio.h里。

C++重要知识点小结---3的更多相关文章

  1. C&plus;&plus;重要知识点小结---2

    C++重要知识点小结--1 :http://www.cnblogs.com/heyonggang/p/3246631.html 1.C++允许程序员声明一个不能有实例对象的类,这样的类惟一的用途是被继 ...

  2. React及Nextjs相关知识点小结

    React及Nextjs知识点小结 函数式组件和类组件区别是什么 1.函数式组件是用于创建无状态的组件,组件不会被实例化,无法访问this中的对象,无法访问生命周期方法,是无副作用的,相比于类组件函数 ...

  3. 【SpringBoot MQ 系列】RabbitMq 核心知识点小结

    [MQ 系列]RabbitMq 核心知识点小结 以下内容,部分取材于官方教程,部分来源网络博主的分享,如有兴趣了解更多详细的知识点,可以在本文最后的文章列表中获取原地址 RabbitMQ 是一个基于 ...

  4. SpringBoot 系列教程之事务隔离级别知识点小结

    SpringBoot 系列教程之事务隔离级别知识点小结 上一篇博文介绍了声明式事务@Transactional的简单使用姿势,最文章的最后给出了这个注解的多个属性,本文将着重放在事务隔离级别的知识点上 ...

  5. disruptor笔记之四:事件消费知识点小结

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  6. promise知识点小结

    断断续续学习es6也有一段时间了,趁着开学空闲对知识点做一些小结. 为什么使用promise 谈到Promise,我们知道,这是社区较理想的异步编程解决方案.想要掌握promise,我们首先要知道其提 ...

  7. shell知识点小结

    目录 引言 shell中的数组 数组的定义 数组的使用 实际的例子 shell中大小的比较 shell中的括号 shell中函数的定义 杂项知识点 字符串转数组 常用判断标志 linux后台运行相关 ...

  8. Vuejs技术栈知识点小结

    前言 上家公司的项目主要是使用jQuery和Angular1,然后自己学了React,没想到来到这家公司突然开始做vue,不过vue还是挺容易上手的.下面是vue技术栈的一些总结,都是来自官网,主要是 ...

  9. Java 基础知识点小结

    小知识点 所有的程序,都要定义在类里面: 异常 定义方法时,使用 throws 可以用来捕获方法体内没有捕获的异常,然后以 SomeException 抛出异常 java是解释型语言.java虚拟机能 ...

随机推荐

  1. 完美解释if-modified-since&sol;not-modified 文件头的意义

    http://www.cnblogs.com/zh2000g/archive/2010/03/22/1692002.html 很好很强大

  2. Mysql 数据库单机多实例部署手记

        最近的研发机器需要部署多个环境,包括数据库.为了管理方便考虑将mysql数据库进行隔离,即采用单机多实例部署的方式.找了会资料发现用的人也不是太多,一般的生产环境为了充分发挥机器性能都是单机单 ...

  3. 谈谈异步加载JavaScript

    前言 关于JavaScript脚本加载的问题,相信大家碰到很多.主要在几个点—— 1> 同步脚本和异步脚本带来的文件加载.文件依赖及执行顺序问题 2> 同步脚本和异步脚本带来的性能优化问题 ...

  4. 什么是LeapMotion

    LeapMotion预览——什么是LeapMotion LeapMotion预览 这个就是LeapMotion: 原文转自:   LeapMotion预览 LeapMotion 官网:http://l ...

  5. Chrome 浏览器数据无法同步,google账号登录失败,提示 Request canceled

    解决方法: 进账号设置不同步 钱包数据 (即取消"Google Pay 中存储的付款方式和地址信息"项的同步) 参考链接: https://www.v2ex.com/t/45285 ...

  6. jar包版本介绍(beta&comma;alpha,release),软件的版本介绍

    α(Alpha) 此版本表示该软件仅仅是一个初步完成品,通常只在软件开发者内部交流,也有很少一部分发布给专业测试人员.一般而言,该版本软件的bug(漏洞)较多,普通用户最好不要安装.主要是开发者自己对 ...

  7. 24&lowbar;ajax请求&lowbar;使用axios

    前置说明: 1.React本身只关注页面,并不包含发送ajax请求的代码 2.前端应用需要通过ajax请求与后台进行交互(json数据) 3.React应用中需要集成第三方ajax库(或自己进行封装) ...

  8. UVA-11882 Biggest Number (DFS&plus;剪枝)

    题目大意:给出一个方格矩阵,矩阵中有数字0~9,任选一个格子为起点,将走过的数字连起来构成一个数,找出最大的那个数,每个格子只能走一次. 题目分析:DFS.剪枝方案:在当前的处境下,找出所有还能到达的 ...

  9. C语言一些总结

    预处理#include<stdio.h>:头文件. stdio.h 标准输入输出. string.h 字符串预处理,. int main()主函数,返回的是int整型, return 0; ...

  10. 使用Having子句

    Having 子句与where子句的功能类似,都是对行进行筛选.但是,where搜索条件是在分组操作之前对记录进行筛选,然后再由group BY 对筛选后符合条件的行进行分组:而Having搜索条件则 ...