一、new的使用
格式1: 指针名 = new 类型;
格式1: 指针名 = new 类型(初始化值 );
格式1: 指针名 = new 类型[元素个数];
2.释放内存
格式1:delete 指针名
格式2: delete[] 指针名 只正对于new数组的情况
3.new malloc的区别(面试题)
第一点:new是c++的,malloc是c的。
第二点:new是运算符 ,malloc是函数,new要快于malloc
第三点:malloc申请失败返回NULL,new申请失败返回异常;
第四点: new和malloc都是在堆区申请的内存
第五点:new是创建对象,创建的对象不需要强转,malloc需要
第六点: new的申请需要delete释放,malloc的申请需要free
4. 注意: new 和delete是运算符 不是函数。
代码:
#include <iostream>
using namespace std;
struct student
{
int age;
};
int main()
{
char* pc = new char(0);
int * pi = new int;
double * pd = new double[10];
struct student* ps = new struct student;
delete pc;
delete pi;
delete[] pd;
delete ps;
}
二、类型转换
c语言类型转换 (类型)变量名
c++四种
第一种: const_cast 把const类型变量转换成非const类型变量
格 式:const_cast<类型> (变量名)
练 习: 定义const指针变量,转换成非const,然后修改值后打印出来
注意: 尖括号不可以省略 小括号不要省略
const_case 的尖括号中必须是指针或者引用类型
第二种:dynamic_cast
作用: 用于多态中类型的转换。(暂时不讲)
第三种:static_cast
作用:用于基本数据类型转换,也可以用于不同类对象的转换(父子类)
格式: static_cast<类型>(变量)
double 转换成int
特点:不会进行安全检查。
第四种:reinterpret_cast
作用: 属于底层的强制类型转换,进行二进制的数据拷贝。
使用: reinterpret_cast <类型>(变量名)
代码:
#include <iostream>
int main()
{
//第一种数据类型转化
int z = 10;
const int* y = &z ;
int* x = const_cast<int*> (y);
cout << (*x) <<endl;
//第二种数据类型转化
double db = 123.8456;
int idb = static_cast<int>(db);
idb++;
cout << idb <<endl;
}
三、面向对象
1.面向对象编程(oop)
主要是为了隔离数据,保护内部数据不被随意修改,同时限定变量的使用区域
2.类定义
定义一个类,有属性(成员变量),有行为(成员函数)。
格式: class 类名
{
修饰符:
定义变量;
定义函数;
};
3.c++中结构体和类的区别
第一个:在结构体中,默认为共有属性,而在类中是私有属性。
4.成员修饰符
共有属性: public: 可以在类内使用(类内函数中),可以在类外使用,可以在子类中使用。
私有属性: private 只可以用于当前类内使用,类外和子类没法使用
保护属性: protected:当前类内使用,子类使用。
5.定义对象:类名 对象名;
对象名.成员变量;
对象名.成员函数();
对象指针 = new 类名称; 使用成员变量是需要用->
对象指针->成员变量
对象指针->成员函数();
6.声明和实现分离
原因:类什么和实现分离时为了隐藏实现部分。
实现接口化编程;
格式:
定义类: class student {public: void show(); };
类外实现: void student::show(){cout <<age <<endl;}
7.成员变量的set和get方法(私有)
get是获取成员变量的值
set是设置成员变量的值。
代码:
#include <iostream>
using namespace std;
class person
{
public:
int age ;
char* name;
void show()//类内定义
{
cout << age <<endl;
}
void display(); //类内声明
int getMoney()
{
return money;
}
void setMoney(int a)
{
age = a;
}
private:
int money;
};
//类外实现。
void person::display()
{
cout << money<<endl;
}
class student
{
private:
int age = 10;
public:
char* name= "abc";
void show();
};
class mynull{};//大小是1
void student::show()
{
cout << age <<endl;
}
int main()
{
person danny;
danny.age = 12;
student huaqing;
// cout << huaqing.name <<huaqing.age << endl;
huaqing.show();
cout << sizeof(mynull)<<endl;
//new的方式创建对象
student * pstu = new student;
pstu->name;
danny.setMoney(100000000);
cout << danny.getMoney()<<endl;
return 0;
}
四、构造和析构
1构造函数:用来构造对象,每个对象创建时都会调用构造函数。
如果没有手动写构造,编译器会自动添加一个。
构造用来做初始化处理,变量的赋值,申请内存。
2格 式: 类名(参数){ 内容}
3注 意:构造函数的函数名是类名相同
构造函数没有返回值
构造函数有参合无参构成了重载
默认的构造函数,没有参数的函数版本 student(){ }
只要手动添加了构造,默认的构造就会消失。
只要手动添加的构造,都必须要有无参构造。(养成好习惯)
4构造调用:构造函数不需要主动调用,当定义对象时会自动调用
对于有参构造,在定义对象时需要加小括号和参数,例如 stduent danny(10);
对于无参构造,直接类名+对象名构建对象,不需要加括号 例如 student danny;
如果某一个对象当做函数的参数,为了防止内存拷贝,需要使用引用。
5.析构函数
作用:在对象释放时内核自动调用析构函数
用来释放内存空间,用来关闭句柄等善后操作
格式:~类名(){}
注意:析构函数的名称是在类名前加~
析构函数不可以主动调用
析构函数没有参数,不可以有参数。
如果没有手动添加析构,编译器会自动添加析构函数。
案例:
class student {
private: int age;
public: student(int a);
student();
~student(){};
void setAge(int a) { age = a; }
int getAge() { return age; }
};
6. 拷贝构造
拷贝构造:他是一种特殊的构造 (没有返回值,函数名是类名),特殊在参数是另外一个对象。
格式: 类名(类名& 对象名){xxxx}
调用: student dannyzai(danny);
student dannyzai = danny; 拷贝构造
fun(student abc){} //避免拷贝构造 加引用
代码:
// 写一个代码:定义一个point类,
// 有x和y坐标(int*),定义构造和拷贝构造,
// 定义析构,在main函数中定义对象。(出现什么错误)
#include <iostream>
#include <cstring>
using namespace std;
class point{
private:
int* x;
int* y;
public:
void setX(int a)
{
*x = a;
}
point(){ //无参构造
x = new int(0);
y = new int(0);
}
point(int a,int b){//有参构造
//x = a;
x = new int(a);
y = new int(b);
}
point(int* a,int* b)//有参构造
{
//错误 x= a;y= b
x = new int (*a);
y = new int(*b);
}
point(point &a);//拷贝构造
}
point::point(point& a){
/* x = a.x;
y = a.y;*/
if(x != NULL)
{
delete x;
}
if(y!= NULL)
{
delete y;
}
//
if(this != &a)//防止引用自己
{
x = new int(*a.x);
y = new int(*a.y);
}
cout << "abc"<<endl;
}
int main(int argc ,char* argv[])
{
point p1; //p1.x p1.y
point p2 = p2; //p2.x = p1.x p2.y = p1.y 错误 doulbe free 两次释放
point p3(10,20);
int * pa = new int(10);
point p4(pa,pa);
delete pa;
p4.setX(10);
return 0;
}
7.拷贝方式:
浅拷贝:浅拷贝只是拷贝了指针指向,不申请内存空间,存在多次释放相同内存的危险,需要避免使用。
注意:如果没有手动写拷贝构造,编译器会自动添加默认的浅拷贝构造函数。
在拷贝构造函数中 要防止自拷贝 if(this != &other)
在拷贝构造中,如果指针不为空,需要先释放内存再进行申请
深拷贝:深拷贝拷贝的是另一个对象的内容,不拷贝地址,新的对象有自己单独的内存空间,不会进行double free的情况。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。