精讲C++
c语言和C++的区别
(1)
struct
默认是public
没有访问权限,没有权限控制
也有this指针
冒号后面是位域,占用几位(bit)
typedef union{
int u;
struct {
char a : 1;
char b : 1;
char c : 10;
char d : 1;
}ST;
}UN3;
class
是正规的oop
(2)
.c 编译器按照C语言的规范来编译
.cpp 编译器按照C++语言的规范来编译
(3)
函数重载
C语言是没有函数重载的
C++语言
oop
1.访问权限
private
public
注意:struct中的成员默认是public的,但class中的成员默认是private的
2. 构造函数,析构函数,拷贝构造函数
这两个函数都是由操作系统在运行时自动调用。构造函数是在创建对象时调用,析构函数是在释放对象时调用
拷贝构造函数 构造函数传一个引用进去
深拷贝 :堆区生成对象
浅拷贝
Teache t2 ;
{
Teacher t1; // 定义作用域,执行完就是否了
}
实例
#include "stdafx.h"
#include<iostream>
#include <tchar.h>
using namespace std;
class Teacher{
public:
Teacher(){
cout << "创建一个老师" << endl;
}
~Teacher(){
cout << "销毁一个老师" << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Teacher *teacher = new Teacher;
delete teacher;
{
Teacher t2;
}
getchar();
return 0;
}
3. C++ 对象的创建方式
java 动态代理的的底层也是反射
new 反射,序列化,clone
1)括号法
Teacher t2(true);
Teacher t1; //直接调用默认构造函数生成对象
不能写成 Teacher t2() ,会当成函数声明
2)显示法
3)隐式转换法
Teacher t3 = true ; 调用的是 Teacher(true){}
#include "stdafx.h"
#include<iostream>
#include <tchar.h>
using namespace std;
class Teacher {
private:
bool isCool;
public:
Teacher(){
cout << "创建一个老师(无参构造)" << endl;
}
Teacher(bool cool){
isCool = cool;
cout << "创建一个老师(有参构造)" << endl;
}
Teacher(const Teacher &teacher){
isCool = teacher.isCool;
cout << "拷贝构造函数" << endl;
}
~Teacher(){
cout << "释放一个老师" << endl;
}
};
int _tmain(int argc,_TCHAR* argv[]){
//1 括号法
Teacher t1;
Teacher t2(true);
Teacher t3(t2);
//2 显示法
Teacher t4 = Teacher();
Teacher t5 = Teacher(true);
Teacher t6 = Teacher(t2);
//3 隐式转换法
Teacher t7 = true;
Teacher t8 = t7;
getchar();
return 0;
}
4.匿名对象
创建对象后马上释放。因为匿名对象在编译器看来就是没有意义的对象。但是如果定义了变量接收匿名对象,则不会创建后马上释放。
#include "stdafx.h"
#include<iostream>
#include <tchar.h>
using namespace std;
class Teacher {
private:
bool isCool;
public:
Teacher(){
cout << "创建一个老师(无参构造)" << endl;
}
Teacher(bool cool){
isCool = cool;
cout << "创建一个老师(有参构造)" << endl;
}
Teacher(const Teacher &teacher){
isCool = teacher.isCool;
cout << "拷贝构造函数" << endl;
}
~Teacher(){
cout << "释放一个老师" << endl;
}
};
int _tmain(int argc,_TCHAR* argv[]){
Teacher();
Teacher t1 = Teacher();
getchar();
return 0;
}
不要使用拷贝构造函数创建匿名函数
Teache();
Teacher t5 = Teacher(true);
Teacher(t5);
5. 拷贝构造函数
如果不定义一个拷贝构造函数,编译器会默认生成一个。
默认的拷贝构造函数执行的是浅拷贝。
调用时机
1.通过一个已创建的对象创建一个新对象
Teacher t1 ;
Teacher t2 = Teacher(t1);
2.值传递
print(t1);
会新创建一个对象
3.函数返回对象
#include "stdafx.h"
#include<iostream>
#include <tchar.h>
using namespace std;
class Teacher {
private:
bool isCool;
public:
Teacher(){
cout << "创建一个老师(无参构造)" << endl;
}
Teacher(bool cool){
isCool = cool;
cout << "创建一个老师(有参构造)" << endl;
}
Teacher(const Teacher &teacher){
isCool = teacher.isCool;
cout << "拷贝构造函数" << endl;
}
~Teacher(){
cout << "释放一个老师" << endl;
}
};
void print(Teacher t){
cout << "print" << endl;
}
Teacher getTeacher(){
Teacher t(true);
return t;
}
int _tmain(int argc,_TCHAR* argv[]){
//1 通过一个已创建的对象创建新对象
Teacher t1(true);
Teacher t2(t1);
//2 值传递
cout << "============" << endl;
print(t2);
//3 函数返回对象
cout << "============" << endl;
Teacher t3 = getTeacher();
getchar();
return 0;
}
6. 深拷贝,浅拷贝
实例
#include "stdafx.h"
#include<iostream>
#include <tchar.h>
using namespace std;
class Teacher {
private:
bool isCool;
int *age;
public:
Teacher(){
cout << "创建一个老师(无参构造)" << endl;
}
Teacher(bool cool,int age){
isCool = cool;
this->age = new int(age);
cout << "创建一个老师(有参构造)" << endl;
}
Teacher(const Teacher &teacher){
age = new int(*teacher.age);
isCool = teacher.isCool;
cout << "拷贝构造函数" << endl;
}
~Teacher(){
if (NULL !=age)
{
delete age;
age = NULL;
}
cout << "释放一个老师" << endl;
}
};
int _tmain(int argc,_TCHAR* argv[]){
{
Teacher t1(true,10);
Teacher t2(t1);
Teacher t4;
}
getchar();
return 0;
}
7. 初始化列表
Teacher() : isCool(bool cool)
{
}
8. 静态成员
1.静态成员属性(类内声明,类外初始化)
// 正确
const static int age = 10;
// 错误
static int age = 10;
2.静态成员方法
只能访问静态成员
可通过类或对象访问(与Java不同)
可通过空指针调用成员函数(成员函数中不得有操作成员属性的代码)
9.计算对象大小
1、普通属性
2、静态属性
3、普通方法
4、静态方法
10. this指针的本质
本质是一个指针常量
Teacher * const this;
11. const
1、常函数
只能修改mutable修饰的成员属性
2、常对象
1、只能修改mutable修饰的成员属性
2、只能调用长函数
友元
1.友元函数
2.友元类
3.友元类方法
运算符重载
1、实现方法:成员函数、全局函数
注意:有的操作符重载只能用全局函数
2.+
//返回值Integer 和返回引用是有区别的 实例 Integer t1(10); cout 《 ++(++t1)《 endl ; cout 《 t1《 endl ; 返回值是 12 11
Integer operator+(){}
#include "stdafx.h"
#include<iostream>
#include <tchar.h>
using namespace std;
class Integer {
public:
int val;
Integer(){}
Integer(int val){
this->val = val;
}
Integer operator+(const Integer &obj){
Integer newObj;
newObj.val = this->val + obj.val;
return newObj;
}
};
int _tmain(int argc,_TCHAR* argv[]){
Integer t1 = 10;
Integer t2(20);
Integer t3 = t1 + t2;
cout << t3.val << endl;
Integer t4 = t1.operator+(t2);
cout << t4.val << endl;
getchar();
return 0;
}
#include "stdafx.h"
#include<iostream>
#include <tchar.h>
using namespace std;
class Integer {
public:
int val;
Integer(){}
Integer(int val){
this->val = val;
}
};
Integer operator+(const Integer &obj1,const Integer &obj2){
Integer newObj;
newObj.val = obj1.val + obj2.val;
return newObj;
}
int _tmain(int argc,_TCHAR* argv[]){
Integer t1 = 10;
Integer t2(20);
Integer t3 = t1 + t2;
cout << t3.val << endl;
Integer t4 = operator+(t1,t2);
cout << t4.val << endl;
getchar();
return 0;
}
注意:运算符重载也可以函数重载,比如Integer需要支持这两种情况下的运算
Integer t3 = t1 + t2;
Integer t3 = t1 + 10;
3.<<
#include <iostream>
using namespace std;
class Integer
{
public:
Integer()
{
this->val = 0;
}
Integer(int val)
{
this->val = val;
}
void operator<<(ostream &out)
{
out << this->val;
}
private:
int val;
};
int _tmain(int argc, _TCHAR* argv[])
{
Integer t1 = 10;
t1 << cout;
// 接收用户的输入
getchar();
return 0;
}
#include <iostream>
using namespace std;
class Integer
{
public:
Integer()
{
}
Integer(int val)
{
this->val = val;
}
int val;
};
void operator<<(ostream &out, Integer &t)
{
out << t.val << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Integer t1 = 10;
cout << t1;
// 接收用户的输入
getchar();
return 0;
}
如果想实现链式操作,怎么做?
4.++
前置
#include <iostream>
using namespace std;
class Integer
{
friend ostream & operator<<(ostream &out, Integer &t);
public:
Integer()
{
this->val = 0;
}
Integer(int val)
{
this->val = val;
}
Integer operator++()
{
this->val++;
return *this;
}
private:
int val;
};
ostream & operator<<(ostream &out, Integer &t)
{
out << t.val;
return out;
}
ostream & operator<<(ostream &out, Integer *t)
{
out << t;
return out;
}
int _tmain(int argc, _TCHAR* argv[])
{
Integer t1 = 10;
// Integer t2 = ++(++t1);
cout << ++(++t1) << endl;
cout << t1 << endl;
// 接收用户的输入
getchar();
return 0;
}
涉及知识点:
1、友元函数
2、返回值与返回引用的区别
后置
注意:必须返回值,不能返回引用(想想为什么)
#include <iostream>
using namespace std;
class Integer
{
friend ostream & operator<<(ostream &out, Integer &t);
public:
Integer()
{
this->val = 0;
}
Integer(int val)
{
this->val = val;
}
Integer operator++()
{
this->val++;
return *this;
}
Integer operator++(int)
{
Integer tmp = *this;
this->val++;
return tmp;
}
private:
int val;
};
ostream & operator<<(ostream &out, Integer &t)
{
out << t.val;
return out;
}
ostream & operator<<(ostream &out, Integer *t)
{
out << t;
return out;
}
int _tmain(int argc, _TCHAR* argv[])
{
Integer t1 = 10;
cout << t1++ << endl;
cout << t1 << endl;
// 接收用户的输入
getchar();
return 0;
}
5.=
知识点:
- 为什么需要重载赋值操作符(深拷贝,如果不深拷贝,执行析构函数时会重复释放)
- 重载赋值操作符的函数中记得释放
- 返回结果应该是返回引用
#include <iostream>
using namespace std;
class Integer
{
friend ostream & operator<<(ostream &out, Integer &t);
public:
Integer()
{
this->val = new int(0);
}
Integer(int val)
{
this->val = new int(val);
}
~Integer()
{
if (NULL != val)
{
delete val;
val = NULL;
}
}
Integer& operator=(Integer &t)
{
this->val = new int(*t.val);
return *this;
}
private:
int *val;
};
ostream & operator<<(ostream &out, Integer &t)
{
out << *t.val;
return out;
}
int _tmain(int argc, _TCHAR* argv[])
{
Integer t1(10);
Integer t2(20);
Integer t3(30);
cout << t1 << endl;
//=====
t2 = t1;
cout << t2 << ", " << t1 << endl;
//=====
t3 = t2 = t1;
cout << t3 << ", " << t2 << ", " << t1 << endl;
// 接收用户的输入
getchar();
return 0;
}
6.>、<、==、!=
7、()
Add()(1, 2)
又称为仿函数
Java中看到函数调用,调用的一定是方法。C++中则不一定,它有可能对应的是一个类
操作符重载的两种方式
1.
2.
练习
1、使用C++实现栈与栈帧
2、使用C++实现线程池
3、重载其他没实现的操作符
上一篇: react antd 项目遇到问题总结