visual studio快捷键
Ctrl+k+u 取消注释
Ctrl+k+c添加注释
1.对象的构造和析构
定义:无论你是否喜欢,对象的初始化和清理工作是编译器强制我们要做的事情。程序自动调用。
使用案例
class Person
{
public:
//构造函数的写法
//与类名相同,没有返回值,不写void,可以发生重载(可以有参数)
//构造函数有编译器自动调用,而不是手动,而且只会调用一次
Person()
{
cout << "构造函数" << endl;
}
//析构函数写法
//与类名相同 前面加一个符号"~",也没有返回值,不写void,不可以有参数
//自动调用,只会调用一次
~Person()
{
cout << "析构函数调用" << endl;
}
};
总结: 1构造函数:没有返回值 没有void,类名相同, 可以发生函数重载, 可以有参数
2没有返回值,没有void,函数名称:~类名, 不可发生=重载,不可以有参数
3如果程序员没有提供构造和析构,系统会默认提供,空实现
分类:
1.按照参数进行分类 无参构造函数(默认构造函数) 有参构造函数
2.按照类型进行分类 普通构造函数 拷贝构造函数
## 2.构造函数的分类及调用注意事项
//分类
//按照参数进行分类 无参构造函数(默认构造函数) 有参构造函数
//按照类型进行分类 普通构造函数 拷贝构造函数
class Person
{
public://构造和析构必须写在public下才可以调用到
Person()
{
cout << "默认构造函数调用" << endl;
}
Person(int a)
{
cout << "有参构造函数调用" << endl;
}
**//拷贝构造函数**
Person(const Person& p)
{
m_Age = p.m_Age;
cout << "拷贝构造函数调用" << endl;
}
~Person()
{
cout << "析构函数调用" << endl;
}
int m_Age;
};
void test01()
{
//构造函数调用方式
//括号发调用
//Person p1(1);//有参
//p1.m_Age = 10;
//Person p2(p1);//拷贝
//cout << "p2的年龄" << p2.m_Age << endl;
//Person p3; //默认构造函数不要加小括号
//显示法调用
Person p4 = Person(100);
Person p5 = Person(p4);
//Person(100); //叫匿名对象,匿名对象待定,如果编译器发现了对象是匿名,那么就在这行代码结束后就释放这个对象
//不能用拷贝构造函数初始化匿名对象
Person p6 = Person(p5);//入过这么写,编译器认为你携程Person p5,对象声明。如果写成右值,那么可以
}
2构造函数调用规则
默认情况下,C++编译器为我们写的类曾加3个函数
1.默认构造函数(无参数,函数体为空)
2.默认析构函数(无参, 函数体为空)
3.默认拷贝构造函数(无参,函数体为空)
用户定义拷贝构造函数,C++不会再提供任何默认构造函数
如果用户定义了普通构造(非拷贝),C++不在提供默认无参构造,但会提供默认拷贝构造
03深拷贝和浅拷贝
1.系统默认提供的拷贝构造 会进行简单的值拷贝
2.如果属性里有指向堆空间的数据,那么简单的浅拷贝会导致重复释放内存
3.解决上述问题,需要我们自己提供拷贝构造函数,进行深拷贝
04初始化列表
//利用初始化列表初始化数据
//构造函数后面 + :属性(参数), 属性(参数)。。。
Person(int a, int b, int c) : m_A(a), m_B(b), m_C(c)
{
}
05类对象作为类成员
1.当类对象作为类的成员时候,构造顺序是先构造类对象的构造,然后构造自己
06 explicit关键字
explicit防止隐式类型转换
07 NEW运算符使用
new Person; //堆区开辟
delete Person;//释放
1.new对象 用void* 去接受,释放不了对象
2.new创建的数组,肯定会调用默认构造
分文件的编写
#include"circle.h"
//设置半径
void Circle::setR(int r)
{
m_R = r;
}
//获取半径
int Circle::getR()
{
return m_R;
}
//设置圆心
void Circle::setCenter(Point p)
{
m_Center = p;
}
//获取圆心
Point Circle::getCenter()
{
return m_Center;
}
//利用成员函数判断点和圆的关系
void Circle::isInCircleByClass(Point & p)
{
//获取圆心和点的距离的平方
int distance = (m_Center.getX() - p.getX()) * (m_Center.getX() - p.getX()) +
(m_Center.getY() - p.getY()) * (m_Center.getY() - p.getY());
int rDistance = m_R * m_R;
if (rDistance == distance)
{
cout << "成员函数判断::点在圆上" << endl;
}
else if (rDistance > distance)
{
cout << "成员函数判断::点在圆内" << endl;
}
else
{
cout << "成员函数判断::点在圆外" << endl;
}
}
类的声明
#pragma once
#include
using namespace std;
#include"point.h"
//圆类
class Circle
{
public:
//设置半径
void setR(int r);
//获取半径
int getR();
//设置圆心
//获取圆心
Point getCenter();
//利用成员函数判断点和圆的关系
void isInCircleByClass(Point & p);
private:
int m_R;//半径
Point m_Center;//圆心
};
07静态成员变量
有两种访问方式
1.通过对象访问属性
2通过类名访问数据
特点:
1.所有对象共享数据
2.只能在类外赋值
08静态成员函数
1.可以访问静态成员变量,不可以访问普通成员变量
2.普通成员函数都可以访问
3.静态成员函数也有权限
4.可以通过对象访问,也可以通过类名进行访问
09单例模式—主席
1.目的为了让类中只有一个实例,实例不需要自己释放
2.将默认构造和拷贝构造私有化
3.内部维护一个对象的指针
4对外提供getinstance方法来访问这个指针
5保证类中只能实例化唯一一个对象
单列模式固定格式
class Printer
{
private:
Printer() { m_Count = 0; };
Printer(const Printer& p) {};
public:
static Printer* getInstance()
{
return singleprinter;
}
void printText(string text)
{
cout << text << endl;
m_Count++;
cout << "打印机使用率次数为: " << m_Count << endl;
}
private:
static Printer* singleprinter;
int m_Count;
};
Printer* Printer::singleprinter = new Printer;
10 C++面向对象模型初探
1成员变量和成员属性是分开存储的
2.空类的大小为1
3.只有非静态成员才属于对象身上