c++核心编程和桌面应用开发

第一天

面向对象基本特征

封装,继承,多态。

命名空间

1.为什么有命名空间,是因为解决多人合作时取标识符重命名的问题。
2.什么是命名空间

//命名空间
namespace A{//A是空间的名字
        int a;
        void func()
        {
        }
   }

3.命名空间的注意
注意1:命名空间只能写在全局
注意2:命名空间可以嵌套命名空间

namespace Maker
{
  int a;
  namespace B
  {
    int b;
  }
}

注意3:命名空间是开放的,随时可以加入新成员,但是新成员只能在加入后使用。
注意4:匿名命名空间
注意5:命名空间可以取别名
注意6:分文件编写代码时,如果.h中有两个命名空间,但是里面的成员函数或成员变量同名时,在.cpp函数中需要添加命名空间。

作用域运算符

namespace Maker
{
   int c=30;
}
//类似于static int d=50
namespace
{
   d=50;
}
//命名空间取别名
void test01()
{
  //
  namespace nameMaker=Maker;
  cout<<nameMaker::a<<endl;
}
int mya=10;
int main()
{
  int mya=20;
  //就近原则
  cout<<"mya="<<mya<<endl;
  cout<<"::mya="<<::mya<<endl;
  cout<<Maker::c<<endl;
  cout<<d<<endl;
  system("pause");
  return EXIT_SUCCESS;
}

1.作用:用来访问某个作用域里面的成员

using声明和编译命令

namespace A
{
  int a=10;
  int b=20;
  int c=30;
}
void test01(){
   //using 声明是让命名空间中某个标识符可以直接使用
   using A::a;
   cout<<a<<endl;
   //int a=50;//注意:using声明了某个变量,在该作用域内不能定义同名的变量。
}
void test02(){
//using编译指令,让某个命名空间中的标识符都可以直接使用
using namespace A;
cout<<a<<b<<c<<endl;
int a=100;//可以。类似于命名空间中的a是全局变量,而这里是局部变量。
}

结构体的加强

//自定义数据类型
struct Maker
{
  char name[64];
  int age;
};
void test01()
{
  Maker a;//不需要加struct就可以定义变量
}
//加强2
struct Maker2
{
  int a;
  void func()//结构体内可以写函数
  {
    cout<<"func"<<endl;
  }

}

更加严格的类型转换检查

//这种方式不能进行隐式转换,必须显示的转换
char *p=(char *)malloc(64);

三目运算符

//c语言例子
void test01()
{
   int a=10;
   int b=20;
   printf("%d\n",a>b?a:b);
   //(a>b?a:b)=100;error
   //这个表达式返回的是右值,是数值,返回的是20
   //20=100;
   *(a>b?&a:&b)=100;
   printf("b=%d\n",b);
}
//c++例子
void test01()
{
   int a=10;
   int b=20;
   //c++的三目运算符返回的是左值,是空间
   (a>b?a:b)=100;
   cout<<"a="<<a<<endl;
   cout<<"b="<<b<<endl;
}

const修饰的变量

1.c语言的const修饰的变量都有空间
2.c语言的const修饰的全局变量具有外部链接属性
3.使用别的文件的全局const修饰的变量需要声明

c语言情况

const int a=10;//常量区,一旦初始化,不能修改;
void test01()
{
  //a=200;全局的const不能直接修改
  int *p=(int*)&a;
  //*p=100;//全局的const不能间接修改
  printf("%d\n",a);
}
int main()
{
  const int b=20;//栈区
  //b=200;局部的const修饰的变量不能直接修改
  int *p=(int*)&b;
  *p=200;//间接可以修改
  printf("%d\n",b);
}

c++情况

1.c++语言的const修饰的变量有时有空间,有时没有空间(发生常量折叠,且没有对变量进行取址操作。)
2.c++语言中const修饰的全局变量具有内部链接属性。
3.在const前加上extern就变为外部连接属性。
4.自定义数据类型,编译器不能优化。
5.如果用变量给const修饰的局部变量赋值,那么编译器不会优化。

const int aa=10;//没有内存
void test01()
{
  //发生了常量折叠
  cout<<"aa="<<aa<<endl;//在编译阶段,编译器:cout<<"aa="<<10<<endl;
  //禁止优化volatile
  volatile const int bb=20;
  //const int bb=20;//栈区
  
  int *p=(int*)&bb;
  *p=200;
  cout<<"a的地址:"<<(int)&bb<<endl;
  cout<<"p指向的地址"<<(int)p<<endl;
  cout<<"bb="<<bb<<endl;//结果为20 编译器优化的结果为cout<<"bb="<<20<<endl
}
int main()
{
  test01();
}

引用的描述

1.引用是做什么:和c语言的指针一样的功能,而且使语法更加简洁。
2.引用是什么:给空间取别名。
3.引用创建时,必须要先初始化。
4.引用一旦初始化不能改变它的指向。
5.引用必须引用一块合法的内存空间。

int a=10;
int &b=a;//给a的空间取别名叫b
b=100;
cout<<a<<endl;
void func(int &a)
{
  a=200;
}
void test2()
{
  int a=10;
  func(a);
  cout<<"a="<<a<<endl;
}
//引用一旦初始化不能改变它的指向
  int a=10;
  int &pRef=a;//给a的空间取别名叫pRef;
  int b=20;
  pRef=b;//赋值操作
  cout<<&a<<endl;
  cout<<&pRef<<endl;//两个地址一样

数组的引用

int arr[]={1,2,3,4,5};
//第一种方法
//1.定义数组类型
typedef int(MY_ARR)[5];//数组类型
//建立引用
MY_ARR &arrf=arr;//建立引用,int &b=a;
//第二种方法
//直接定义引用
int (&arref2)[5]=arr;//int &b=a;
//第三种方法
typedef int(&MY_ARR3)[5];//建立引用数组类型
MY_ARR3 arref3=arr;

尽量用const替代define

1.define无数据类型,const有数据类型。
2.const修饰的变量有作用域,define修饰的变量无作用域。

指针的引用

char* p="李明";
char* &p1=p;
cout<<p1<<endl;
//二级指针,用来装一级指针变量的地址
//被调函数
void func(char**temp)
{
  char *p=(char*)malloc(64);
  memset(p,0,64);
  strcpy(p,"小花");
  *temp=p;
}
char* mp=NULL;
fun(&mp);
cout<<mp;

引用的使用场景

1.引用作为函数参数
2.引用作为函数的返回值

常量引用和bool类型

//普通引用
int a=10;
int &ref=a;
ref=20;

//int &ref2=10;//不能给字面变量取别名
const int &ref3=10;//可以给const修饰的引用赋予字面量
//const修饰符修饰的引用的原理
//编译器会把上面的代码变为:int tmp=10;const int &ref3=tmp;

内联函数

//宏函数
#define ADD(x,y) x+y
//在普通函数前面加上inline是向编译器申请成为内联函数
//注意:加inline可能成为内联函数,也可能不能成为内联函数
//什么情况不会成为内联函数
//1.存在过多的条件判断语句
//2.函数体过大
//3.对函数进行取址操作
//内联函数的优势:有宏函数的效率,没有宏函数的缺点。
//类的成员函数默认加上inline
inline int Add(int x,int y)
{
	return x+y;
}
void test()
{
    //10+20*2
	int ref=ADD(10,20)*2;
	cout<<"red="<<ref<<endl;
}
#define COMPAD(x,y) ((x)<(y)?(x):(y))
void test2()
{
	int a=1;
	int b=3;
    //                    ((++a)<(b)?(++a):(b)) a自增两次
	cout<<"COMAPD(x,y)="<<COMPAD(++a,b)<<endl;//结果为3
}

函数的默认参数和占位参数

1.注意1:函数的默认参数后面的参数必须都是默认参数
2.注意2:函数的声明和实现不能同时有函数的默认参数

int myFunc(int a,int b=0)//int b=0;这就是函数的默认参数,不一定是0
{
	return a+b;
}
void test01()
{
	//函数的默认参数的作用
	//当函数内常要用到形参的某个值,但偶尔要使用其他值
	cout<<myFunc(10,20)<<endl;
	cout<<myFunc(10)<<endl;

}
void myFun3(int a,int b);
void myFun3(int a,int b=0)
{
}
//函数的占位参数,占位参数在后面区分前加加或后加加
void func(int a,int b=10)//占位参数也可以有默认值
{

}
func(10);

函数重载

1.在c++中允许出现同名的函数,这种现象称为函数重载。
2.函数重载的作用:是为了方便使用函数名。
3.函数重载的条件:参数的个数不同,同一个作用域,参数的顺序不同,参数的类型不同。
满足四个中任意一个即可。
4.函数的返回值不能作为函数重载的条件
编译器是通过你调用函数时,传入的参数来判断调用重载的哪个函数,我们调用函数时不需要写返回值,所以返回值不能作为函数重载的条件。

函数重载的原理

1.函数重载的原理是在汇编时,给各个函数取别名,c语言不能重载的原因是没有取别名。

c++调用c语言的函数

1.c++的函数在汇编时,会给函数取别名,c语言不会,这时,如果c++来调用c语言的函数,c++会取找取了别名的函数,但是c语言没有取别名,这时会出错。

//这是在告诉c++编译器,找下面的函数,要以c语言的方式去寻找。
#ifdef __cplusplus
extern "C"
{
#endif
	void func();
	
#ifdef __cplusplus
}
#endif

构造函数和析构函数的概念

//构造函数的作用是初始化成员变量,是编译器去调用的
//实例化对象,内部做了两件事,1.分配空间2.调用构造函数进行初始化

匿名对象

1.匿名对象的生命周期在当前行

Maker();
//注意,如果匿名对象有名字来接,那么就不是匿名对象。
Maker m1=Maker(); 

构造函数的调用规则

//如果程序员提供了有参构造,那么编译器不会提供默认的构造函数,但是会提供默认的拷贝构造。
//如果程序员提供了拷贝构造函数,那么编译器不会提供默认的构造函数和默认的拷贝构造函数。

多个对象的构造函数和析构函数

//如果类有成员对象,那么先调用成员对象的构造函数,在调用本身的构造函数。
//析构函数的顺序反之
//2.成员对象的构造函数调用和定义顺序一样
//3.注意,如果有成员对象,那么实例化对象时,必须保证成员对象的构造和析构能被调用。
//4.如果有多个对象需要指定调用某个构造函数,用逗号隔开。
//5.可以使用对象的构造函数传递数值给成员对象的变量。
  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

煎饼果子小鸢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值