(C++)面向对象语言(关键字)

目录

一、面向对象

1、C++发展

2、为什么学C++?

3、面向对象与面向过程

4、面向对象语言的三要素

二、C到C++过度

1、作用域限定符(::)

2、命名空间

(1)如果一个函数里面经常要访问某个命名空间的成员,通过using关键词识别,这样操作这个成员的时候就不需要命名空间来访问了。

(2)在一个函数中如果已经对某个命名空间的成员通过using 标识,就不能再对其它同名的不同的命名空间的成员进行标识

(3)如果再一个代码中都要使用某一个命名空间中的成员,可以通过using标识整个命名空间,这样,这个命名空间中的所有成员都可以访问,一般放在最上面。

3、输入/输出函数(cout/cin)

4、register 关键字

C与C++的不同点:

5、struct 关键字

C与C++的不同点:

6、bool类型

7、三目运算符

C与C++的不同点:

8、const关键字

C与C++不同点:

9、C++引用

(1) 概念: c++提供了给变量取别名的机制,就是引用,引用时对c语言的一个扩充

(2)引用的本质:常指针

(3)引用作为函数的返回值

(4)指针引用(给指针取别名)

(5)常引用

10、内联函数

注意事项:

11、C++函数中默认参数

12、C++函数中占位参数(一般与默认参数一起使用)

13、C++函数重载

三个条件:

(1)函数名相同

(2)函数的参数的个数或类型或顺序不同(const int  与 int  也可以区分)

(3)和函数的返回值类型无关

14、C++的动态内存分配

初试new 与 delete:

C与C++的不同:

多维数组的创建和释放:


一、面向对象

ubuntu:安装g++编译器

命令:sudo apt-get install g++

1、C++发展

C++98标准 -----> C++03------>C++11------>C++14

2、为什么学C++?

应用领域: 应用软件开发 游戏开发 多媒体开发 人工智能

3、面向对象与面向过程

C语言:面向过程

(1)强调做算法

(2)大程序被分割成很多小程序,这些小程序被称为函数

(3)数据开放特点(封装性差)

C++:面向对象

特点:

(1)面向对象按照类来分隔组织程序,每个类都有特定的属性和方法,使得软件就像搭积木一样,更加容易组织

(2)维护代码的更少修改

4、面向对象语言的三要素

封装:把客观的事物封装成类,并且类中实现自己的数据和方法,对于不可信的进行信息隐藏。

继承:类和类之间的关系,省去了重复开发的时间

多态:同一个接口,不同的功能,也称为多种形态

二、C到C++过度

1、作用域限定符(::

作用域限定符(域解析符):主要用于操作全局定义的变量或者类或者函数等等。

#include <iostream>  //标准输入输出流
using namespace std;
int num = 100;
void test1()
{
    printf("num = %d\n",num);   //两种输出效果相同
    cout<<"num = "<<num<<endl;  //cout:输出函数  <<:输出运算符 ,链式输出,endl:换行
    int num = 888;
    //::作用域限定符(域解析符):主要用于操作全局定义的变量或者类或者函数等等
    cout<<"num = "<<::num<<endl;
}
int main(int argc, char const *argv[])
{
    test1();
    return 0;
}

2、命名空间

目的:为了解决合作开发或者不同代码端之间的命令冲突问题,c++因此引入命名空间的概念

使用注意事项:

(1)如果一个函数里面经常要访问某个命名空间的成员,通过using关键词识别,这样操作这个成员的时候就不需要命名空间来访问了。

(2)在一个函数中如果已经对某个命名空间的成员通过using 标识,就不能再对其它同名的不同的命名空间的成员进行标识

void test2()
{
    //如果一个函数里面经常要访问某个命名空间的成员,通过using关键词识别,这样操作这个成员的时候就不需要命名空间来访问了
    using zhangsan::num;
    cout<<"张三的num:"<<num<<endl;
    num = 1000;
    cout<<"张三的num:"<<num<<endl;
    //在一个函数中如果已经对某个命名空间的成员通过using 标识,就不能再对其它同名的不同的命名空间的成员进行标识
    //using Lisi::num;
    //cout<<"lisi的num:"<<num<<endl;
    using Lisi::myfun;
    myfun();
}

(3)如果再一个代码中都要使用某一个命名空间中的成员,可以通过using标识整个命名空间,这样,这个命名空间中的所有成员都可以访问,一般放在最上面。

using namespace zhangsan;
void test3()
{
    cout<<num<<endl;
    myfun();
}

3、输入/输出函数(cout/cin)

输入,输出:cin,cout

#include <iostream> //头文件:输入输出流
using namespace std;  //使用标准命名空间
void test1()
{
    int a = 100;
    printf("a = %c\n",a);
    int ch = 'w';
    printf("ch = %c\n",ch);
    char b = 'w';
    char c[] = "hello world";
    float d = 3.141592685;
    cout<<"a = "<<a<<endl;
    //输出十六进制
    //printf("a = %#x\n",a);
    cout<<hex<<a<<endl;
    //输出八进制
    cout<<oct<<a<<endl;
    cout<<"b = "<<b<<endl;
    cout<<"c = "<<c<<endl;
    cout<<"d = "<<d<<endl;
}
void test2()
{
    //int a;
    //cin>>a;  //>>:输入运算符
    cout<<dec;
    //cout<<"a = "<<a<<endl;


    int a,b,c;
    cin>>a>>b>>c;
    cout<<"a = "<<a<<" b = "<<b<<" c = "<<c;
    cout<<endl;
}
int main(int argc, char const *argv[])
{
    cout<<"hello world"<<endl;  //cout:标准输出流对象 endl:换行
    test1();
    test2();
    return 0;
}

4、register 关键字

作用:被register关键词声明的对象直接放在寄存器,大大提升了变量的访问速率

C与C++的不同点:

C语言中:register关键词修饰的变量不可以用&操作符取地址

c++中:可以对一个寄存器变量取地址,register关键词变为无效,会被强制放入内存中存储(成为普通变量)

5、struct 关键字

C与C++的不同点:

C语言中:内部不允许定义函数

C++中:可以定义函数;struct命名的结构体名字可以直接作为类使用;

//定义一个结构体
struct chinese
{
    char name[32];

//c语言中内部不允许定义函数
//c++可以
    void myfun()
    {
        printf("hello world!\n");
    }
};

struct USA
{
    char name[32];
};

//C语言代码
void IntroChinese(struct chinese *ch)
{
    printf("%s是一个中国人\n",ch->name);
}
void IntroUSA(struct USA *ch)
{
    printf("%s是一个外国人\n",ch->name);
}
int main(int argc, char const *argv[])
{
    struct chinese ch = {"张三"};
    struct USA u = {"BOB"};
    IntroChinese(&ch);
    IntroUSA(&u);
    
    return 0;
}


//C++代码
void IntroChinese(chinese *ch)
{
    printf("%s是一个中国人\n",ch->name);
}
void IntroUSA(USA *ch)
{
    printf("%s是一个外国人\n",ch->name);
}
int main(int argc, char const *argv[])
{
    chinese ch = {"张三"};
    USA u = {"BOB"};
    IntroChinese(&ch);
    IntroUSA(&u);
    
    return 0;
}

6、bool类型

true 为 1;false 为 0;(占一个字节)

#include <iostream>
using namespace std;
//c++支持bool类ing,可以赋值为true,或者false,占一个字节
int main(int argc, char const *argv[])
{
    bool a = true;
    cout<<"a = "<<a<<endl;
    bool b = false;
    cout<<"b = "<<b<<endl;
    a = -0.00000001;
    cout<<"a = "<<a<<endl;
    cout<<"sizeof(bool) = "<<sizeof(a)<<endl;
    return 0;
}

7、三目运算符

C与C++的不同点:

C语言:三目运算符返回的是一个常量

C++:返回的是一个变量

#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
    int a = 1,b = 2;
    int num = (a > b)?a:b;
    
    (a > b)?a:b = 100;  //C语言中,返回的是一个数值,c++中,返回的是一个变量
    return 0;
}

8、const关键字

C与C++不同点:

C语言:const修饰的是只读变量,但是可以通过地址来修改其值。

C++:是一个真正的常量,不可以通过地址或者变量来修改其值,因为其存放在符号表中,所以也就是说,不能对其取地址;但是当对const修饰的变量取地址的话, 系统会为其分配一定内存空间,并且用常量来填充。

 图中 a 的值是不变的,也就是说,C++中 不可修改。

#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
    const int a = 1;
    //a++;
    int *p = (int *)&a;  
//对const修饰的常量取地址,编译器会分配一个整形的长度,并且把数字1填写到对应的内存中
    *p = 2;
    cout<<"a = "<<a<<endl;
    cout<<"*p = "<<*p<<endl;
    return 0;
}

9、C++引用

(1) 概念: c++提供了给变量取别名的机制,就是引用,引用时对c语言的一个扩充

《注意》:typedef:是给数据类型取别名,不能对变量进行重命名。

下面是通过引用实现,两个数的互换:

int &c = a;  //引用一定要初始化
//int &d = 100;   //不能用常量初始化引用

#include <iostream>
using namespace std;

void Swap(int &x,int &y)
{
    int tmp = x;
    x = y;
    y = tmp;
}
int main(int argc, char const *argv[])
{
    int a = 100,b = 200;
    cout<<"交换前:"<<"a = "<<a<<" b = "<<b<<endl;
    Swap(a,b);
    cout<<"交换后:"<<"a = "<<a<<" b = "<<b<<endl;

    int &c = a;  //引用一定要初始化
    c = 1000;
    cout<<"a = "<<a<<endl;
    //int &d = 100;   //不能用常量初始化引用

    return 0;
}

(2)引用的本质:常指针

当分析复杂语法现象的时候,当作常指针来分析,分析一般语法,当别名分析

struct test
{
    int &a;   //其相当于一个常指针,大小为8个字节,两个为16个字节
    char &c;
};

int main(int argc, char const *argv[])
{
    int a = 1;
    char c = 'c';
    int &pa =a;
    char &pc = c;
    //int &pb = c;   //左右类型要一致

    cout<<"sizeof(test) = "<<sizeof(test)<<endl;  
//当分析复杂语法现象的时候,当作常指针来分析,分析一般语法,当别名分析
    cout<<"sizeof(pa) = "<<sizeof(pa)<<endl;
    cout<<"sizeof(pc) = "<<sizeof(pc)<<endl;
    return 0;
}

(3)引用作为函数的返回值

注意:引用作为函数的返回值时,不能返回局部数据(局部变量,局部对象,局部数组等)的引用,因为当函数调用完成后,局部数据都会被销毁,数据不存在了。可以返回一个全局变量或者静态变量的引用。

将引用作为函数返回值的函数,有4中处理方式:

1> 不接收函数返回值

2> 用一个普通变量接收函数返回值,这个时候接收的是变量的值而不是变量的引用

3> 用一个引用接收函数返回值,接收的就是一个引用

4> 当成左值使用

#include <iostream>
using namespace std;
int g = 100;

int& f1()
{
    int x = 1;
    return g;
}

int main(int argc, char const *argv[])
{
    //用法1:不接受函数返回值
    f1();
    //用法2:用一个普通变量去接收函数的返回值,返回的是g的值
    int a = f1(); 
    a = 1000;
    cout<<"a = "<<a<<endl;
    cout<<"g = "<<g<<endl;
    //用法3:用一个引用去接收函数的返回值,接收的就是一个引用
    int &b = f1();
    b = 1000;
    cout<<"b = "<<b<<endl;
    cout<<"g = "<<g<<endl;
    //用法4:当成左值使用
    f1() = 200;   //g = 200;
    cout<<"g = "<<g<<endl;
    return 0;
}

(4)指针引用(给指针取别名)

用指针引用代替二级指针:

#include <iostream>
#include <cstdlib>
#include <cstring>

using namespace std;

typedef struct student{
    int id;
    char name[32];
}ST;

void ceate_student(ST* &stu)   //取代了二级指针
{
    stu = (ST *)malloc(sizeof(ST));
    if(stu == NULL)
    {
        cout<<"malloc error"<<endl;
        exit(-1);
    }

    stu->id = 100;
    strcpy(stu->name,"bxp");
}

void printf_student(ST *stu)
{
    cout<<"id = "<<stu->id<<" name = "<<stu->name<<endl;
}

int main(int argc, char *argv[])
{
    ST *stu = NULL;

    ceate_student(stu);  //无需取地址
    printf_student(stu);


    return 0;
}

(5)常引用

常引用:指不能通过引用来改变引用对象的值

使用方法:

1>使用普通变量初始化常引用

int a;
const int &b = a; //b是a的常引用,a和b代表同一块内存空间,但是不能通过b修改a的值

2>使用常量初始化常引用(不可以用常量初始化普通引用)

const int &num = 10;
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
    int a =1;
    const int &b = a;
    //b = 2;  //不能通过常引用修改其值
    const int &pb = 100;   //可以用常量初始化常引用
    //int &pd = 100;   //不可以用常量初始化普通引用
    int *p = (int *)&pb;
    (*p)++;
    //pb++;
    cout<<"pb = "<<pb<<endl;
    return 0;
}

10、内联函数

内联函数:在编译时将函数调用处直接用函数体替换,类似于C语言中的宏展开。这种在函数调用处直接嵌入函数体的函数叫做内联函数(内嵌函数/内置函数)

内连函数创建方法:只需要在函数定义处增加关键字inline。

#include <iostream>
using namespace std;
//只需要在函数定义处加关键词inline即可
inline int MyMax(int a,int b)
{
    return (a > b) ? a: b;
}
#define MAX(a,b) (a) > (b) ? (a):(b)
int main(int argc, char const *argv[])
{
    int a = 1,b = 2;
    cout<<MyMax(1,2)<<endl;
    int ret = MAX(++a,b);
    cout<<"ret ="<<ret<<endl;
    return 0;
}

注意事项:

1>.不能存在任何形式的循环语句

2>.不能存在过多的条件判断语句

3>.函数体不能过于庞大

4>.不能对函数进行取地址操作

5>.函数内联声明必须在函数调用之前

总结:内联函数比普通函数省去了函数调用时压栈,跳转,和返回等开销,因此,当函数体的开销远大于压栈,出栈等开销时,内联函数会变得没有意义。

11、C++函数中默认参数

c++中可以给形参一个默认的值,当我们在使用函数时,如果不传参,则使用这个默认值。

使用方法:

默认参数:将一个值设置为默认参数,那么右边所有的参数都必须设置默认值

如果给默认参数传参,则使用传的参数,不使用默认值

#include <iostream>
using namespace std;

//默认参数:将一个值设置为默认参数,那么右边所有的参数都必须设置默认值
//如果给默认参数传参,则使用传的参数,不使用默认值
void Add(int x,int y = 0,int z = 1)  //设置y的默认值为1,int y = 1被称为默认参数
{
    cout<<"x + y = "<<x + y<<endl;
}
int main(int argc, char const *argv[])
{
    Add(1);
    return 0;
}

12、C++函数中占位参数(一般与默认参数一起使用)

占位参数没有初始值时,函数调用时需要传参。

void Add(int a,int b,int = 0)   //一般和默认参数一起使用
{
    cout<<a+b<<endl;
}
int main(int argc, char const *argv[])
{
    Add(1,2);
    cout<<sizeof(A)<<endl;
    return 0;
}

13、C++函数重载

三个条件:

(1)函数名相同

(2)函数的参数的个数或类型或顺序不同(const int  与 int  也可以区分)

(3)和函数的返回值类型无关

#include <iostream>
using namespace std;
void Swap(int &a,int &b)
{
    int tmp = a;
    a = b;
    b = tmp;
}
/*int Swap(int &a,int &b)  //和返回值类型无关
{
    int tmp = a;
    a = b;
    b = tmp;
    return 1;
}*/
void Swap(int &a,double &b)  //参数的类型不同
{
    int tmp = a;
    a = b;
    b = tmp;
}
void Swap(int &a,int &b,int &c)  //参数的个数不同
{
    int tmp = a;
    a = b;
    b = tmp;   
}
void Swap(double &b,int &a)  //参数的顺序不同
{
    int tmp = b;
    b = a;
    a = tmp;
}
int main(int argc, char const *argv[])
{
    int a =100,b = 200,c;
    Swap(a,b);
    cout<<"a = "<<a<<" b = "<<b<<endl;
    double d = 3.14;
    Swap(a,d);
    Swap(a,b,c);
    Swap(d,a);
    return 0;
}

函数重载的二义性:以下代码会产生二义性

14、C++的动态内存分配

初试new 与 delete:

C语言: 动态内存分配使用malloc函数,释放使用free函数。

C++中:malloc和free函数仍然可以使用,但是我们更多会使用new和delete,为c++类和对象设计

C与C++的不同:

(1)new/delete是关键词,malloc/free是函数

(2)malloc和free的返回值是void*类型,new/delete返回值类型为申请对象的指针类型

(3)malloc申请空间的时候不能初始化,new可以初始化

(4)malloc不能自动调用类的构造函数,free不会自动调用析构函数,new和delete可以。

#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
    int *p = new int;    //分配了1个int型的内存空间,返回值类型为int*类型
    *p = 100;
    cout<<"*p = "<<*p<<endl;
    delete p;  //释放p指向的内存空间
    p = NULL;
    int *q = new int(200);  //申请对象空间的同时,并且对申请的空间初始化为200
    cout<<"*q = "<<*q<<endl;
    delete q;
    q = NULL;
    int *q2 = new int[5]{1,2,3,4,5};   //c++11标准,c++11前不可以初始化动态数组
    
    /*for(int i = 0; i < 5;i++)
    {
        q2[i] = i;
    }*/
    for(int i = 0; i < 5;i++)
    {
        cout<<q2[i]<<" ";
    }
    cout<<endl;
    delete []q2;  //释放一个数组
    q2 = NULL;
    return 0;
}

多维数组的创建和释放:

例:二维数组的动态创建,例如申请存放二维数组 int a[5][6]的空间

例:三维数组的动态创建,例如申请存放二维数组 int a[5][6][7]的空间;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值