C++学习2
1.C++传统的左值引用
1.引用必须初始化,指针不一定要初始化
2.引用初始化的时候引用哪块内存,就永远无法引用别的内存。
3.定义一个引用变量开辟一个指针大小的内存 存被引用对象的地址
4.引用比指针更安全(引用需要初始化 指针可能是野指针)
5.指针有一级二级 引用只有一级引用
指针和引用的区别是什么?
从指令看:
1.从指令上看,定义引用和指针是没有区别的。
把a的地址放在eax里面,再把eax的值放在p的内存里
int a = 10;
int *p = &a; lea eax,[a] mov dword ptr[p], eax
int &b=a; lea eax,[a] mov dword ptr[b], eax
2.从指令上看通过指针修改它所指向的值和通过引用修改它所引用的值是一样的。
把p的内存(p里面放着a的地址)放到寄存器里,再把20放到p里放的地址里,这样就改变了a的值
*p = 20; mov eax, dword ptr[p] mov dword ptr[eax], 14h
b = 30; mov eax, dword ptr[b] mov dword ptr[eax], 1Eh
从内存方面:
1.引用必须初始化,指针不一定要初始化
2.引用初始化的时候引用哪块内存,就永远无法引用别的内存。
3.定义一个引用变量开辟一个指针大小的内存 存被引用对象的地址
4.引用比指针更安全(引用需要初始化 指针可能是野指针)
5.指针有一级二级 引用只有一级引用
PS:
交换的时候用swap(&a,&b)
因为可以自动执行引用操作
void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void swap(int &a, int &b)//引用
{
int tmp = a;
a = b;
b = tmp;
}
void sort(int (&p)[6], int size)
{
cout << sizeof(p) << endl;
}//24 出来是和原本一样的大小
void sort(int *p, int size)
{
cout << sizeof(p) << endl;
}//4
int main()
{
//int a = 10;
//int b = 20;
//swap(&a, &b);
//swap(a, b);
//cout << "a:" << a << " b:" << b << endl;
}
传参的一种手法
传变量的引用来做参数 可以直接改变变量的值
(当需要返回两个参数的时候 也可以一个传引用 一个正常的返回值)
int main( )
{
char time[32];
backtime(time);
}
void backtime(char (&tmp)[32])//绝妙的手法!!传变量的引用来做参数 可以直接改变变量的值
{
time_t t = time(0);
strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&t));
// cout << tmp << endl;
/*
time_t now_time;
now_time = time(NULL);
cout << now_time;
return now_time;*/
}
2.类和对象
1.面对对象语言的四大特性:
抽象 封装 继承 多态
2.类和类之间常见的关系
组合 继承
组合:a part of …一部分
继承:a kind of…一种
代理:一个类的端口集合是另一个类的端口组合的子集(一个类的功能实现依赖于另一个类)
组合:一个类是另一个类的一部分
3.说一说怎么理解OOP的?
类–》 描述 --》 实体类型的一个抽象说明( 是一种 属性 行为)
类 实例化 对象 《=》 实体
实体的属性 =》 类的成员变量
实体的行为 =》 类的成员方法(函数)
对象
成员 占空间 类型不占空间
成员方法可以在类内实现 也可以在类外实现
4.类:用来抽象实体类型的**
类的访问限定符:public公有的 private私有的 virtual
5.class和struct的区别?**
struct的默认访问限定是public的
class的默认访问限定是private
class A
{
public:
A(int a1, int a2)
:_a1(a1),_a2(a2)//构造函数才有初始化列表
{}
private:
//Const 引用 都要初始化
const int _a1;
int& _a2;
};
/*
**初始化 就是在对象的空间获取的时候给值
**对象的构造过程:
**获取空间
**构造
*/
/*
**类的编译顺序
**先编译 类名
**再编译 成员名
**后编译 方法体
*/
/*
**new 对象 申请内存 调用构造
**delete 对象 调用析构 释放内存
*/
class B
{
public:
B(int a1, int a2, int b1, int b2)
:a(a1, a2) //先构造成员对象//class A没有默认构造函数要再调用B构造函数前调用A构造函数
{
_b1 = b1;
_b2 = b2;
}
private:
int _b1;
int _b2;
A a;
};
/*
组合类的构造顺序
先构造成员对象
再构造本对象
6.请解释一下多态是什么?
` 静态(编译)的多态: `函数重载
` 动态(运行)的多态: `
编译器编译C/C++源码,会产生很多符号 =>> 存在符号表中
C 产生函数符号 只与函数名有关
C++ 产生函数符号 与函数名 + 形参列表有关
7.函数重载
1. 函数名相同,参数列表不同。可以构成函数重载,不能仅通过函数返回值来区分函数重载
2. 必须处于同一作用域
类和对象理解:
#include <iostream>
using namespace std;
const int STR_SIZE = 20;
// 抽象化一个实体 商品
class CGoods
{
public: // 行为 - 成员方法
// 初始化商品属性信息
void init(const char *n, int a, double p)
{
strcpy(this->mName, n);
this->mAmount = a;
this->mPrice = p;
}
// 打印商品的所有属性信息
void show();
private: // 属性 - 成员变量
char mName[STR_SIZE];
int mAmount;
double mPrice;
};
void CGoods::show()
{
cout << "name:" << this->mName << endl;
cout << "amount:" << this->mAmount << endl;
cout << "price:" << this->mPrice << endl;
}
int main()
{
// const char *p = "hello world";
/*
CGoods可以定义无数个对象
每一个对象都有自己的一份成员变量
但是所有对象共享一份成员方法
问题:在成员方法中,怎么区分倒地处理的是哪个对象的数据?
this指针是干什么用的?
所有类的成员方法,编译以后,都会添加一个形参变量
就是当前类类型的this指针 CGoods *this.
当用对象调用成员方法时,实际上生成的指令,会把调用方法
的对象的地址当作实参进行传递,赋给this指针。
this指针指向的就是调用该成员方法的对象
*/
CGoods good1;
//
//init(&good1, "商品01", 100, 50.0)
good1.init("商品01", 100, 50.0);
//show(&good1)
good1.show();
CGoods good2;
// init(&good2, "商品02", 200, 70.0)
good2.init("商品02", 200, 70.0);
// show(&good2)
good2.show();
return 0;
}
3.new和malloc delete和free 区别
new和malloc的区别?
1.malloc是C的库函数,而new是C++的运算符
2. malloc开辟内存和类型无关,返回的是void*,需要进行类型强转;
而new运算符开辟内存需要指定具体类型,返回值不需要强转
3. new不仅可以开辟内存 还可以初始化
new int[10];而malloc只能开辟内存
4.malloc开辟内存失败,返回空指针;而new开辟内存失败,抛出的是bad_alloc类型的异常
5.malloc是按字节数开辟内存的 malloc (sizeof(int)) malloc (sizeof(int)*10);而new按类型个数开辟的 需要指定类型
6. malloc只对应一个free操作,而new对应两个delete
操作 delete ptr delete [ ]ptr(数组空间)
delete和free的区别?
1.delete是运算符,free是C的库函数
2. free只能释放内存,delete先调用指针指向的对象的析构函数 再释放内存(free)
3. free释放单个元素和元素数组的内存的方式是一样的,而delete是有区分的
delete ptr delete [ ]ptr
Person p =new Person[100]
delete p----只调用一次 释放数组首地址的外部资源 剩下的外部资源都泄露掉了
delete []p----调用100次析构函数 把外部资源释放掉
new 开辟内存 调用构造函数
new的四种方法:
1>new nothorow int(10)
不抛异常的new,出错的话返回值是空指针
2>new const 在堆栈上开辟了20个常量空间 const int *p=new const int(20)
3>new int --》出错会抛异常
4> 定位new
new(ptr) T(obj) —》int *p = new(addr)int(20)
定位new,在已经开辟好的内存上构造对象,ptr是指定内存的地址
代码演示:
#include <iostream> // #include <stdio.h>
using namespace std;
int main()
{
//int a = int(); // char() short() long() char*()
//cout << "a:" << a << endl;
//new int[20]和new int[20]()的区别是什么?
new int[20]()是取内置类型默认的零值 new出来数组的二十个元素 元素都初始化为0
new int[20] new出来数组的二十个元素 new出来是啥就是啥
//请把new的四种方式都说一下?
#if 0
int *p = (int*)malloc(sizeof(int));
if (p == nullptr)
{
return -1;
}
*p = 20;
free(p);
try
{
// 把可能发生异常的代码扩在try块里面
int *p1 = new int(20);
delete p1;
}
catch (bad_alloc &err)
{
cout << "new alloc mem error!" << endl;
}
int *parr = (int*)malloc(sizeof(int) * 20);
//这个是开辟数组内存 往进去赋值的时候需要for循环进行赋值
if (parr == nullptr)
{
return -1;
}
free(parr);
try
{
int *parr1 = new int[20](30);
delete[]parr1;
}
catch (bad_alloc &err)
{
}
#endif
return 0;
}
4.C和C++如何互相代码调用
C和C++代码怎么调用?
_cplusplus
用C语言实现的库函数可以给C或者C++项目
(给头文件用 可以让C的接口不仅用在C 也用在C++)
在C++里怎么调用C的代码?
需要把调用函数接口声明的代码都括在extern “C” 里面 但是注意这个extern “C”只有C++编译器才能识别
所以#ifdef__cplus*plus C编译器没有这个宏 所以不会看到 extern “C”这个东西
C怎么调用C++?
把C++的源代码都括在extern “C”里面
/
/ 防止头文件被重复包含
#ifndef SUM_H
#define SUM_H
/*
extern "C"<=只有C++编译器才能识别
告诉C++编译器,里面的函数接口都是在C下编译生成
的
*/
#ifdef __cplusplus
extern "C"
{
#endif
int sum(int, int);
#ifdef __cplusplus
}
#endif
结构体的大小:
在C里面是1
C++里面是0