new和delete
在学习C++的过程中,有一套区别于C的内存分配,这个就是new和delete这两个关键字
申请释放内存
#include<iostream>
using namespace std;
int main()
{
//申请内存
int *p1 = (int *)malloc(sizeof(int));
*p1 = 1;
int *p2 = new int;
//int *p2 = new int(2); //分配内存的同时初始化
*p2 = 2;
cout << *p1 << " " << *p2 << endl;
//释放内存
free(p1);
delete p2;
return 0;
}
分配多个内存
#include<iostream>
using namespace std;
int main()
{
int *p3 = new int[3]; //分配多个内存
//int *p3 = new int[3]{ 1,2,3 }; //分配内存的同时初始化
for (int i = 0; i < 3; ++i)
{
p3[i] = i;
cout << p3[i] << ' ';
}
cout << endl;
delete[] p3; //释放内存
return 0;
}
注意:
- 这里需要注意的是分配内存并初始化时使用的是花括号
- delete[] 指针用来释放多个内存
动态分配内存
#include<iostream>
using namespace std;
//数组指针作为函数返回值 列为固定值的受限动态内存分配
int(*create(int row))[3]
{
int(*p)[3] = new int[row][3];
return p;
}
int main()
{
//受限制的动态内存分配
int(*p4)[3] = create(4);
int index = 1;
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 3; j++)
{
p4[i][j] = index++;
cout << p4[i][j]<<" ";
}
}
cout << endl;
delete[] p4;
return 0;
}
- 这里就比较有意思了,当函数返回值为数组指针时,函数怎么写,大部分人是一脸懵逼的,这是声明一个返回数组指针的函数 int (*create(int row))[3]
- delete[] p4一定要记得加[]
类和对象
什么是对象:万物皆对象,l拥有相同属性和行为的一组对象
有了对象之后就会累(类),那什么类:类是现实世界对象的抽象,对象是类虚拟世界的实例
简单表示就是:类是一种用户自定义的数据类型,包括表示属性的成员变量和表示行为的成员函数
说到面向对象就不得不提面向对象的三大特性继承,封装和多态
类的关键字是:class
在对class描述之前需要了解到一个规则:访问控制权限
既然有访问控制权限,那就有访问类型限定符
访问类型限定符
- public 共有成员
谁都可以访问(使用/调用)
- protected保护成员
只有自己和子类可以访问
- private 私有成员
只有自己(类内部)可以访问
类和结构体区别
在C++中,类和结构没有本质区别,唯一不同在于
类的默认访问控制属性为private
结构的默认访问控制属性为public
封装
对不同成员的控制访问属性加以区分,体现了C++作为面向对象语言的封装特性
定义一个类
接下来就是类的介绍了,今天是情人节,所以我们定义一个女朋友类
class GirlFrend
{
//属性 成员变量
char m_name[20];
int m_age;
int m_height;
char m_job[20];
public:
//行为 成员函数
void Introduce();
void Sleep();
void Eat();
void SetInformation(char* name, int age, int height, char* job);
};
作为类,我们需要有属性和行为,也就是成员变量和成员函数
我呢实在类内声明,类外定义
void GirlFrend::Introduce()
{
cout << "你好!我叫" << m_name << "我今年" << m_age << "岁,身高" << m_height << ",我的职业是" << m_job << endl;
}
void GirlFrend::Sleep()
{
cout << "睡觉觉~" << endl;
}
void GirlFrend::Eat()
{
cout << "吃饭饭~" << endl;
}
void GirlFrend::SetInformation(char* name, int age, int height, char* job)
{
strcpy(m_name, name);
m_age = age;
m_height = height;
strcpy(m_job, job);
}
然后呢在主函数里面创建你的女朋友对象,并初始化你的女朋友
int main()
{
//栈区对象
GirlFrend girl;
girl.SetInformation("女朋友", 18, 165, "白衣天使");
girl.Introduce();
girl.Sleep();
girl.Eat();
//堆区对象
GirlFrend* myGirl = new GirlFrend;
myGirl->SetInformation("女朋友", 18, 160, "白衣天使");
myGirl->Introduce();
myGirl->Sleep();
myGirl->Eat();
return 0;
}
运行结果:
你好!我叫女朋友我今年18岁,身高165,我的职业是白衣天使
睡觉觉~
吃饭饭~
你好!我叫女朋友我今年18岁,身高160,我的职业是白衣天使
睡觉觉~
吃饭饭~
在行为里面有一个函数用来设置对象,为什么不直接赋值,而要定义这样一个函数来初始化对象。
因为class这个关键字的默认访问控制属性为private,意味着只有这个类自己和子类可以访问m_name,m_age这些变量,这个就体现了C++作为面向对象语言的封装特性,我有这个东西,可如果不是我和我儿子,谁都别想访问,就是这么霸道
string类
C++在对字符串的操作上提供了string类
在C里面我们是如何使用字符串的呢
//使用字符数组
char str[] = "hello";
//使用字符指针
char* s = (char*)"world";
//直接使用字符常量
printf("hello world\n");
在C++里面是这样使用字符串的
头文件
#include<string> //注意不是string.h
使用字符串对象 string类创建对象
#include<iostream>
#include <string>
using namespace std; //string在命名空间 std 里面
int main()
{
//创建string类对象
string s1 = "123";
string s2("abc");
string* s3 = new string("xyz");
//赋值
s1 = s2; //相比C strcpy 更方便
//比较
if (s1 == s2)
{
cout << "s1 = s2" << endl;
}
//拼接
s1 = s1 + "456";
s1.append("789");
s1.push_back('!');
cout << s1 << endl;
//交换
s1.swap(s2);
cout << s1 << " " << s2 << endl;
//字符串长度
cout << s2.size() << endl;
//查找 替换
cout << s2.find("456", 0) << endl;
s2.replace(s2.find("456", 0), //第 n 个位置开始替换
3, //替换的字符数量
"888"); //替换的字符串
cout << s2;
return 0;
}
运行结果
s1 = s2
abc456789!
abc abc456789!
10
3
abc888789!