文件输入输出
主要分为
开关文件 打开模式 文件状态 读写位置 读写文件 将输入缓冲区与关联数据同步
cpp
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string testfile = "testfile.txt";
//out写入文件binary二进制处理\r\n不处理
//输出默认清空源文件的内容
fstream wfs(testfile, ios::out|ios::binary);
//等同于wfs.open(testfile, ios::out| ios::binary);
wfs << "1234567890\n";
wfs.close();//用完记得关闭
ofstream ofs;//app追加写入
ofs.open(testfile, ios::app | ios::binary);//这些与操作,都是特定的宏定义数字
ofs << "1234\n" << flush;//输出文本,自动读到\0可用flush主动刷新
ofs.write("1234\n", 5);//输出二进制,write精准控制长度,不能自动刷新
ofs.write("1asd", 4);
//读取文件
fstream rfs(testfile, ios::in | ios::binary);
if (!rfs.is_open())
{
cerr << "open file" << testfile << "failed!" << endl;
return -1;
}
char buf[1900]{0};
rfs.read(buf, sizeof(buf) - 1);
cout << rfs.gcount() << endl;
cout << buf << endl;
rfs.close();
//获取文件大小ios::ate文件尾部
ifstream ifs(testfile, ios::ate | ios::binary);
cout << ifs.tellg() << endl;//trllg读取文件指针当前位置
//读取文件更改后的内容
string line;
while (1)
{
if (getline(ifs, line)) // 如果成功读取到一行
{
if (!line.empty())
cout << "line: " << line << endl;
}
else // 没有新内容可读
{
ifs.clear(); // 清除EOF状态
ifs.seekg(0, ios::end); // 将读指针移动到文件末尾,准备继续等待新内容
}
}//做不出效果,找不出问题
std::cout << "Hello World!\n";
}
面向对象
类
用户定义的类型 :是一个集合了数据和处理程序的组件 class
对象 object
一个类有多个对象 自定义类的变量 类型-》实体
他的第一个作用是去简略代码重复度
感觉有点像加上一个内部函数的结构体
cpp
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//两个npc 有血量有名字
//处理npc被攻击
//string npc1_name = "npc1";
//int npc1_health = 100;
//
//string npc2_name = "npc2";
//int npc2_health = 100;
//
//void AtackNpc1(int atk)
//{
// npc1_health -= atk;
//}
//
//void AtackNpc2(int atk)
//{
// npc2_health -= atk;
//}//简单C语言直接编写很麻烦
////我们可以使用数组简化
//vector<string>npcs_name{"npc1","npc2"};
//vector<int>npcs_health{100,100};
////但是在具体处理过程中可能会有很多数据,而且使用数组会产生覆盖问题
//void AtackNpc(int index, int atk)
//{
// npcs_health[index-1] -= atk;
//}
//在C++的开发中又多了一个选择使用类
class Npc
{
public:
string name_;
int health_ = 100;
void Atack(int atk)
{
health_ -= atk;
cout << name_ << " : " << health_ << endl;
}
};
//类型名称 首字母大写 ,每个单词首字母大写
class MyClass
{
public://在外部也能访问
//成员变量
int x{ 0 };//C++11开始可以在声明时赋值
int y{ 0 };
char name[16]{ "what name" };
void Testin(int v)//内联函数的定义
{
//this指针 当前类对象的地址
cout << "this addr =" << this << endl;
x += v;//其实这里省略了this完整板
//this->x += v;
//也可以继续使用内部函数
this->Testout(100);
(*this).Testout(1000);
y += v;
cout << "x " << x << " y " << y << endl;
}
void Testout(int v);//成员函数的声明和定义是分开的
};
void MyClass:: Testout(int v)//可以加快编译
{
x += v;
y += v;
cout << "x " << x << " y " << y << endl;
}
int main()
{
MyClass mc1;//栈区对象
cout << "sizeof(mc1) " << sizeof(mc1) << endl;
//访问方式就是用.
mc1.x = 10;
cout << mc1.x << " : " << mc1.y << endl;
//也可以使用指针,和结构体一样指针访问用->
MyClass* mc2 = new MyClass;//在堆里申请要释放
mc2->x = 5;
cout << mc2->x << " : " << mc2->y << endl;
cout << (*mc2).x << " : " << (*mc2).y << endl;//也可以转化成对象进行访问
delete mc2;
MyClass* mc3 = &mc1;//也可以
MyClass mc4 = mc1;//支持直接赋值
Npc npc1;
npc1.name_ = "npc1";
Npc npc2;
npc2.name_ = "npc2";
MyClass mfs;
cout << "&mfs =" << &mfs << endl;
mfs.Testin(10);//内联函数是直接把函数复制过来
mfs.Testout(10);
npc1.Atack(10);
npc2.Atack(20);
}
静态成员变量与函数访问说明符
|--------------|------------------|-----------------|
| 特性 | 静态成员变量 | 普通成员变量 |
| 存储位置 | 静态存储区(全局区) | 栈或堆(取决于对象创建方式) |
| 生命周期 | 程序开始到结束 | 对象的生命周期内 |
| 所属关系 | 属于类(所有对象共享) | 属于具体对象(每个对象独有) |
| 访问方式 | 类名::变量名 或 对象.变量名 | 对象.变量名 |
| 初始化 | 必须在类外单独初始化 | 可以在构造函数初始化列表初始化 |
| 内存分配 | 程序加载时分配 | 创建对象时分配 |
| 个数 | 只有一份拷贝 | 每个对象有一份拷贝 |
cpp
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//类型名称 首字母大写 ,每个单词首字母大写
class MyClass
{
public://在外部也能访问
//成员变量
int x{ 0 };//C++11开始可以在声明时赋值
int y{ 0 };
char name[16]{ "what name" };
void Testin(int v)//内联函数的定义
{
//普通成员函数可以访问 私有静态成员
count++;
cout << "count = " << count << endl;
y += v;
cout << "x " << x << " y " << y << endl;
}
void Testout(int v);//成员函数的声明和定义是分开的
//静态成员变量声明
static int size;//静态成员变量的声明和定义是分开的
//静态成员函数
static void TestStatic()
{
//没有this指针,不能访问非静态成员变量
count++;
cout << "TestStatic" << endl;
//x++//非静态成员变量无法访问
}
//单件模式 类的对象只存在一份
static MyClass& Instance()
{
static MyClass mc;
return mc;
}//在多项程中的应用比较广泛,列表多任务使用一个变量
//静态成员函数2 私有成员函数封装成普通函数
//因为静态函数可以访问私有成员和私有函数
static void RunStatic(MyClass& obj)
{
obj.Run();
}
private://public公开
//private私有,只有(静态)成员函数可以访问
static int count;
void Run(void)
{
cout << "RunStatic" << endl;
}
};
//静态成员变量定义
int MyClass::size{ 0 };
int MyClass::count{ 0 };
void MyClass::Testout(int v)//可以加快编译
{
x += v;
y += v;
cout << "x " << x << " y " << y << endl;
}
int main()
{
MyClass::Instance().Testin(100);
//这样就会产生全局唯一的一个类
//私有private只有内部成员可以访问
//MyClass::count++;
MyClass::size++;
cout << "MyClass::size = " << MyClass::size << endl;
MyClass::TestStatic();
MyClass mc;
MyClass::RunStatic(mc);
mc.Testin(1);
mc.Testin(1);
}
构造函数和析构函数
构造函数
名字就是类的名字本身,可以内联,在创建对象的时候自动发生,但是全局对象的构造函数在main函数之前调用
析构函数
~类的名字,可以内联,在销毁对象的时候会自动使用,比如栈区对象出作用域,堆区对象被清空,全局对象在程序结束使用
堆区对象的创建
使用new
New的使用过程
先申请空间用malloc 和C语言是一样的
然后转换地址格式 如果是类的话就转换成类指针
再然后初始化成员
最后进入构造函数
new在创建堆区类的时候就会有这四步
要记得释放,恢复指针指向
类成员初始化
1 默认成员初始化 简单将就是在定义的时候初始化 一次
2 构造函数的成员初始化列表 优先级大于1
3 构造函数直接赋值 尽量少用,会增加开销
cpp
#include <iostream>
using namespace std;
class MyClass
{
public:
//构造函数
MyClass()//函数名就是类的名字
{
cout << "Creat MyClass" << endl;
}
//析构函数
~MyClass()//在这个类被销毁的时候自动触发
{
cout << "break MyClass" << endl;
}
//想要访问成员变量就定义一个函数返回出来
int index(void) { return index_; }
//想要改值就这样
void set_index(int i) { index_ = i; }
private ://不要开放任何成员变量到public
//1 默认成员初始化
int index_{ count_++ };//加一个_代表是成员变量
static int count_;
};
int MyClass::count_{ 0 };
MyClass mc0;//但是全局对象的构造函数在main函数之前调用
//全局变量的销毁是在所有程序运行完后
int main()
{
cout << "main begin" << endl;
////堆区构造析构函数
//{
// cout << "堆区实验" << endl;
// MyClass* cp1 = new MyClass();
// //MyClass* cp1 = new MyClass;//加上()会把说有没初始化的值默认初始化为0,
// delete cp1;//调用析构函数
// //delete 只释放空间,不修改指针值,也就是说指针还存在
// cp1 = nullptr;//C++指针清零用这个
// auto cp2 = new MyClass();//内存泄露
// //程序退出会释放,但是不调用析构函数
//}
//MyClass mc1;//在创建对象的时候会自动使用构造函数
//MyClass mc2;
}