C++入门知识点总结

Wesley13
• 阅读 554

一、C++中的命名空间

C++中使用命名空间来解决在相同文件或范围的同名变量问题,示例程序如下:

#include <iostream>
using namespace std;

#if 0
int g_count = 100;

int g_count = 200;  //error,重命名错误
#endif

namespace stuname   //定义命名空间stuname
{
    const char *name = "zhangsan";  //定义命名空间中stuname的变量name
}

namespace homename   //定义命名空间homename
{
    const char *name = "xiaozhang";  //定义命名空间中homename的变量name
}

int main()
{
    cout << "school : " << stuname::name << endl;   //访问stuname命名空间中的数据

    cout << "homename : " << homename::name << endl;   //访问homename命名空间中的数据
}

二、C++标识符声明使用的三种方法

C++的所有标识符都被定义在一个名叫std的namespace(命名空间)里,要想使用这些标识符,则必须先声明,声明有以下3种方法:

int main()
{
     #if 0   //第1种:直接声明使用
        std::cout<<"hello world"<<std::endl;
     #endif
 
    #if 0   //第2种:先用using声明要使用的标识符
        using   std::cout;
        using   std::endl;
         cout<<"hello world"<<endl;
     #endif
 
     #if 1   //第3种:声明使用标准命名空间中所有内容(即标识符)
         using   namespace   std;    //一般申明在头文件后
         cout<<"hello world"<<endl;
     #endif
 
     return  0;
}

三、自动类型转换的四种情况

在C/C++中有以下四种情况会发生自动类型转换:

#include <iostream>
#include <stdlib.h>
#include <string.h>

using namespace std;

int add(double  num1,double num2)
{
    return  num1+num2;
}

int main()
{
    //第1种:赋值
    int i = 3.14;   //转换成int型
    cout << "i=" << i << endl;

    //第2种:运算时
    double res = 4 + 3.14;  //4运算前转换成double型
    cout << "res=" << res << endl;

    //第3种: 函数调用实参与形参不一致时,自动转换成形参类型
    //第4种:当返回值类型与函数返回类型不一致时,自动转换成函数返回类型
    int result = add(2,3);  //2,3转换成double型,5再转换成int型
    cout << "result=" << result << endl;

    return  0;
}

四、引用的使用

引用就是某一变量(目标)的一个别名,对引用的操作与对变量的直接操作完全一样。

引用的声明方法:类别标识符 **&**引用名 = 目标变量名。

示例程序如下所示:

int a;
int &ra=a; //定义引用ra,它是变量a的引用,即别名。

说明:

  • &在此处不是取地址运算,而是标识作用。
  • 声明引用时,必须对其进行初始化。
  • 引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量的别名。
  • 声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,他本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。因此对引用求地址,就是对目标变量求地址。
  • 不能建立数组的引用,因为数组是一个由若干个元素组成的集合,所以无法建立一个数组的别名。

五、C++内联函数

C++中支持内联函数,其目的是为了提高函数的执行效率,使用关键字 inline 可将函数指定为内联函数,内联函数通常就是将它在程序中的每个调用点上“内联地”展开,假设我们将 max 定义为内联函数:

inline int max(int a, int b)
{
    return a > b ? a : b;
}

调用: cout<<max(a, b)<<endl;,在编译时展开为: cout<<(a > b ? a : b)<<endl;从而消除了把 max写成函数的额外执行开销。

C++ 语言的函数内联机制既具备宏函数的效率,又增加了安全性,而且可以自由操作类的数据成员。所以在 C++ 程序中,应该用内联函数取代所有宏函数,“断言 assert”恐怕是唯一的例外。


注意

  • 代码过长,多于3行,则编译器会忽略 inline 限定符。
  • 在类定义中的定义的函数都是内联函数,即使没有使用 inline 说明符。
  • 函数内不能有复杂结构,例如for循环和开关语句。

六、C++多态相关

1、虚函数声明如下:virtual ReturnType FunctionName(Parameter) 虚函数必须实现,如果不实现,编译器将报错,错误提示为:

error LNK****: unresolved external symbol "public: virtual void __thiscall ClassName::virtualFunctionName(void)"

2、虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。


3、在有动态分配堆上内存的时候,析构函数必须是虚函数,但没有必要是纯虚的。且基类的析构函数必须是虚函数,否则会析构不完全。


4、友元不是成员函数,只有成员函数才可以是虚拟的,因此友元不能是虚拟函数。但可以通过让友元函数调用虚拟成员函数来解决友元的虚拟问题。


5、C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数;形成多态必须具备三个条件:

  • 必须存在继承关系;
  • 继承关系必须有同名虚函数(其中虚函数是在基类中使用关键字Virtual声明的函数,在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数);
  • 存在基类类型的指针或者引用,通过该指针或引用调用虚函数;

6、父类的虚函数或纯虚函数在子类中依然是虚函数。有时我们并不希望父类的某个函数在子类中被重写,在 C++11 及以后可以用关键字 final 来避免该函数再次被重写。

例:

#include<iostream>

using namespace std;

class Base
{
    public:
        virtual void func()
        {
            cout<<"This is Base"<<endl;
        }
};

class _Base:public Base
{
    public:
        void func() final//正确,func在Base中是虚函数
        {
            cout<<"This is _Base"<<endl;
        }
};

class __Base:public _Base
{
/*    public://不正确,func在_Base中已经不再是虚函数,不能再被重写
        void func()
        {
            cout<<"This is __Base"<<endl;
        }*/
};

int main()
{
    _Base a;
    __Base b;
    Base* ptr=&a;
    ptr->func();
    ptr=&b;
    _Base* ptr2=&b;    ptr->func();
    ptr2->func();
}

/*
输出结果:

This is _Base
This is _Base
This is _Base
*/

如果不希望一个类被继承,也可以使用 final 关键字。

格式如下:

class Class_name final
{
    ...
};

则该类将不能被继承。


七、C++ 函数传递参数的三种方式

(1)值传递

当进行值传递时,就是将实参的值复制到形参中,而形参和实参不是同一个存储单元,所以函数调用结束后,实参的值不会发生改变。程序示例如下:

#include <iostream> 
using namespace std; 

void swap(int a,int b)
{
    int temp; 
    temp=a;
    a=b;
    b=temp;
    cout<<a<<","<<b<<endl; // 2,1
}

int main()
{
    int x=l; 
    int y=2; 
    swap(x,y);
    cout<<x<<", "<<y<<endl; // 1,2
    
    return 0;
}

(2)指针传递

当进行指针传递时,形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。这种方式还是 “值传递”,只不过实参的值是变量的地址而已。而在函数中改变的不是实参的值,而是实参地址所指向的变量的值。程序示例如下:

#include <iostream> 
using namespace std; 

void swap(int *a,int *b)
{
    int temp; 
    temp=*a;
    *a=*b;
    *b=temp;
    cout<<*a<<","«*b«endl; // 2,1
}

int main()
{
    int x=l; 
    int y=2; 
    
    swap(&x,&y);     
    cout<<x<<","<<y<<endl; 2,1
    
    return 0;
}

也就是说,在进行函数调用时,不仅交换了形参的值,而且交换了实参的值。


(3)引用传递

实参地址传递到形参,使形参的地址取实参的地址,从而使形参与实参共享同一单元的方式。程序代码示例如下:

#include <iostream> 
using namespace std; 

void swap(int &a,int &b) 
{
    int temp; 
    temp=a; 
    a=b; 
    b=temp;
    cout<<*a<<","<<*b<<endl; // 2,1
}

int main()
{
    int x=l; 
    int y=2; 
    swap(x,y);
    cout<<x<<","<<y<<endl; // 2,1
    
    return 0;
}

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这