C++学习(8)(文件输入输出,类和对象(1))

文件输入输出

主要分为

开关文件 打开模式 文件状态 读写位置 读写文件 将输入缓冲区与关联数据同步

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;


}
相关推荐
历程里程碑1 小时前
26信号处理一:从闹钟到进程控制的奥秘
linux·运维·服务器·开发语言·c++·算法·排序算法
jghhh011 小时前
基于C# WinForm实现自动在线升级的方案
开发语言·c#
Gofarlic_OMS1 小时前
LS-DYNA许可证全局状态及集群计算资源使用可视化监控大屏
运维·开发语言·算法·matlab·自动化
阿里嘎多学长1 小时前
2026-02-25 GitHub 热点项目精选
开发语言·程序员·github·代码托管
载数而行5201 小时前
算法系列4之插入排序
数据结构·c++·算法·排序算法
dengzhenyue1 小时前
MFC 学习笔记
笔记·学习·mfc
智者知已应修善业1 小时前
【查找指定字符串首位置与数量不区分大小写完整匹配】2025-5-3
c语言·c++·经验分享·笔记·算法
troublea1 小时前
ThinkPHP vs Laravel:PHP框架终极对决
开发语言·php·laravel
Ronin3052 小时前
信道管理模块和异步线程模块
开发语言·c++·rabbitmq·异步线程·信道管理