面向对象第五讲
类型转换
C语言中存在隐式类型转换:char < int < long < float < double
int num = 5;
double b = num;//将整型隐式转化成double
num = 'a';//将字符隐式转换成整型
C语言中存在强制类型转换
int num = 5;
int *p = #
char *ptr = (char *)p;//将p强制转换成char型
缺陷:C中强制类型转换不安全,能把任何类型都强制转化,不做类型检查
C++新类型转换运算符:
注:C++也支持隐式类型转化
static_cast: 相关类型转化;void *和其他类型之间的转化;父类和子类之间的转化
int num = 5;
double b = static_cast<double>(num);
char ch = static_cast<char>(num);
int *p_num = #
void *p = p_num;//void *是万能指针,能接收任何类型指针的值
char *ptr = static_cast<char *>(p);
reinterpret_cast: 可以将任意类型指针做转换(类似于C的强制类型转换,不安全)
//接上代码
ptr = reinterpret_cast<char *>(p_num);
const_cast: 去除指针和引用的const 属性(很少用,危险,使用该运算符意味着代码设计存在缺陷)
const int count = 5;
int count1 = 6;
const int *p_count = &count;
//count int *p_count = &count1;//编译不通过
//int *p_count1 = p_count;//报错,如果正确则能通过*p_count1修改count的值
int *p_count1 = const_cast<int *>(p_count);
*p_count1 = 7;//能实现
const int &r_count = count;
int &r_count1 = const_cast<int &>(r_count);//引用也同样适用
dynamic_cast(多态讲)
C++封装
C++ 用类和对象实现封装
封装作用:提高代码的维护性,保证代码的独立性(高内聚,低耦合)
C:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int num;
struct nude *next;
};
typedef struct nodeNode;
typedef Node * Link;
Link head;
void init_link()
{
head = NULL;
}
void insert_head_node(Link *newnode)
{
(*newnode)->next = head;
head = *newnode;
}
int display_link()
{
if(head == NULL)
{
return 0;
}
Link temp = head;
while(temp != NULL)
{
printf("%d\n",temp->num);
temp = temp->next;
}
}
int main()
{
Link head;
Link newnode;
init_link();
for(int i = 0 ; i < 10 ; i++)
{
newnode = (Link)malloc(sizeof(Node));
newnode->num = i + 1;
insert_head_node(&newnode);
}
display_link();
return 0;
}
C++:
link.h:
#pragma once
struct Node
{
int num;
struct node *next;
}
class Link
{
public:
void initLink();
void insertHeadnode(node *newnode);
//void inserttailNode(node *newnode);
//void insertModNode(node *newnode, int num);
//void delectNode(node *newnode);
void displayLink();
node * getHead();
private:
node *head;
}
link.cpp:
#include <iostream>
#include "link.h"
using namespace std;
void Link::initLink()
{
head = nullptr;
}
void Link::insertHeadNode(node *newnode);
{
newnode->next = head;
head = newnode;
}
void Link::displayLink()
{
node * temp = head;
while(temp != nullptr)
{
printf("temp = %d\n",temp->num);
temp = temp->next;
}
}
main.cpp:
#include <iostream>
#include "link.h"
using namespace std;
int main()
{
Link link;
link.initLink();
for(int i = 0; i < 10; i++)
{
node *newnode = new node;
newnode->num = i+1;
link.insertHeadNode(newnode);
}
link.displayLink();
return 0;
}
写一个计算器:
cal.h:
#pragma once
#include <iostream>
#include <string>
using namespace std;
class Cal
{
public:
double getPesult();
void setNum1(double a);
void setNum2(double b);
void setOp(string op);
private:
double num1;
double num2;
string op;
}
cal.cpp:
#include "cal.h"
void Cal::setNum1(double a)
{
num1 = a;
}
void Cal::setNum2(double b)
{
num2 = b;
}
void Cal::setOp(string op)
{
op = op;
}
double Cal::getResult()
{
if(op == "+")
{
return num1 + num2;
}
else if(op == "-")
{
return num1 - num2;
}
}
main.cpp:
#include <iostream>
#include "link.h"
#include "cal.h"
using namespace std;
int main()
{
Cal cal;
cal.setNum1(1.0);
cal.setNum2(2.0);
cal.setOp("+");
double result = cal.getResult();
cout << result << endl;
return 0;
}
this指针
指向当前操作对象,对各成员的访问均通过this进行
为什么需要this指针?
因为同一个类实例的对象共享代码段(方法),为了区分访问哪个对象的成员,所以编译器会在编译阶段给类的所有方法加上this指针参数,用来指向当前操作的对象。
构造函数
用来初始化对象成员的值
引入作用:防止忘记初始化
特点:
1.函数名与类名相同
2.函数没有返回值
3.可以重载
4.可以自动调用
构造函数种类:
默认无参构造函数;有参构造函数;拷贝构造函数;类型转换构造函数;移动构造函数
析构函数
释放对象成员所分配的内存空间
引入目的:防止内存泄漏
特点:
函数名是~类名;无参;不可重载;没有返回值;当对象被释放,会先调用析构函数