[zz]C++中成员初始化列表的使用

本文介绍了C++中构造函数的两种初始化方式,并重点讨论了在什么情况下应当使用成员初始化列表,包括当成员为对象、const修饰或引用类型时的具体应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


 C++在类的构造函数中,可以两种方式初始化成员数据(data member)。
1,在构造函数的实现中,初始类的成员数据。诸如:
class point
{
private:
 int x,y;
public:
 point(int m=0,int n=0)
 {
  x=m;
  y=n;
 }
 int GetX()
 {
  return x;
 }
 int GetY()
 {
  return y;
 }
};
2,还可以定义初始化成员列表(Initializer list)来初始化成员数据(data member)。
  改写构造函数如下:
 point(int m=0,int n=0):x(m),y(n)
 {
 }
这样咋一看没有什么不同,确实,对于上面的这种简单列子来说,也真的没有太大不同。
 
那我们为什么要用初始化成员列表,什么时候用初始化成员列表来初始化成员数据呢?Lippman的《C++ Primer》中提到在以下三种情况下需要使用初始化成员列表:
 
一,需要初始化的数据成员是对象的情况;
二,需要初始化const修饰的类成员;
三,需要初始化引用成员数据;
 
现在分别举例说明:
一,需要初始化的数据成员是对象。
---------------------------
#include <stdio.h>
class point
{
protected:
 int m_x,m_y;
public:
 point(int m=0,int n=0)
 {
  m_x = m;
  m_y = n;
  printf("constructor called!/n");
 }
 point(point& p)
 {
  m_x = p.GetX();
  m_y = p.GetY();
  printf("copy constructor called!/n");
 }
 int GetX()
 {
  return m_x;
 }
 int GetY()
 {
  return m_y;
 }
};
 
class point3d
{
private:
 point m_p;
 int m_z;
public:
 point3d(point p, int k)
 {
  m_p = p;                              //这里是对m_p的赋值
  m_z=k;
 }
 point3d(int i,int j, int k):m_p(i,j)   // 相当于 point m_p(i,j)这样对m_p初始化
 {
  m_z=k;
 }
 void Print()
 {
  printf("%d,%d,%d /n",m_p.GetX(),m_p.GetY(),m_z);
 }
};
---------------------------------------
上述代码中Point3d是一个3D坐标,他有一个point的2D坐标和一个成员组成。
我们现在想定义一个3D坐标p3d,可以这样实现:
void main()
{
 point p(1,2);    //先定义一个2D坐标
 point3d p3d(p,3);
 p3d.Print();
}
从point3d实现体可以看出,我们是通过对m_p进行赋值,这样不仅调用copy constructor产生临时对象而且是对m_p的一个赋值操作。
而如果使用成员初始化列表,我们则可以这样:
void main()
{
 point p(1,2);
 point3d p3d(1,2,3);
 p3d.Print();
}
p3d中的point型成员是通过调用初始化的方式构建的。由于对象赋值比初始化要麻烦的多,因此也带来的性能上的消耗。(可以参见Scott Meyers著《effective C++》条款12)。
这也是我们在对成员数据是对象成员的采用初始化列表进行初始始化的主要原因。
 
二,需要初始化const修饰的类成员;
三,需要初始化引用成员数据;
对于类成员是const修饰,或是引用类型的情况,是不允许赋值操作的,(显然嘛,const就是防止被错误赋值的,引用类型必须定义赋值在一起)因此只能用初始化列表对齐进行初始化。
上面两点比较好明白,可以用一个例子加以说明:
-------------------------------------
#include <stdio.h>
class base
{
private:
 const int a;
 int& b;
public:
// base(int m, int n)
// {
//  a = m;
//  b = n;
// }
 base(int m, int n):a(m),b(n)
 {}
};
 
void main()
{
 base ba(1,2);
}
---------------------------
上面红色的部分初始化的方式是不允许的通不过编译,通过初始化列表则可以很好的定义。

 

<think>我们使用zlib库在C++中进行文件压缩。以下是一个简单的示例,展示如何使用zlib压缩一个文件。步骤:1.打开源文件(待压缩文件)和目标文件(压缩后的文件)。2.使用zlib的deflate函数进行压缩。3.将压缩后的数据写入目标文件。注意:zlib提供了一系列函数,我们主要使用compress函数(这里我们使用更灵活的方式,因为文件可能较大,需要分块处理)。由于zlib的压缩函数一次处理整个数据块可能不适用于大文件,因此我们采用分块压缩的方式。我们将使用gzip文件格式,因为zlib支持gzip格式。这里我们使用zlib的gzFile系列函数来简化操作。但是,用户要求使用zlib(而不是gzip的接口),所以我们使用基本的zlib流式压缩API。以下是一个使用zlib的deflate进行压缩的示例代码:注意:需要链接zlib库(-lz)代码步骤:a.打开源文件和目标文件(二进制模式)。b.初始化zlib的deflate流。c.循环读取源文件数据块,压缩并写入目标文件。d.结束压缩并清理资源。我们将写一个函数来压缩文件。注意:这里我们使用Z_DEFAULT_COMPRESSION,也可以指定压缩级别(0-9)。示例代码:</think>以下是使用 zlib 在 C++ 中压缩文件的示例代码,包含详细注释: ```cpp #include <iostream> #include <fstream> #include "zlib.h" bool compressFile(const std::string& inputPath, const std::string& outputPath) { // 打开输入文件(二进制模式) std::ifstream inFile(inputPath, std::ios::binary | std::ios::ate); if (!inFile) { std::cerr << "无法打开输入文件: " << inputPath << std::endl; return false; } // 获取文件大小并重置指针 const size_t fileSize = inFile.tellg(); inFile.seekg(0); // 读取文件内容到缓冲区 char* inputBuffer = new char[fileSize]; inFile.read(inputBuffer, fileSize); inFile.close(); // 准备输出缓冲区(压缩后大小通常小于等于源大小 + 0.1% + 12字节) uLong compressedSize = compressBound(fileSize); Bytef* outputBuffer = new Bytef[compressedSize]; // 执行压缩 int result = compress2( outputBuffer, // 输出缓冲区 &compressedSize, // 输入:缓冲区大小,输出:实际压缩大小 reinterpret_cast<Bytef*>(inputBuffer), // 输入数据 fileSize, // 输入数据大小 Z_BEST_COMPRESSION // 最高压缩级别 ); if (result != Z_OK) { std::cerr << "压缩失败: " << (result == Z_MEM_ERROR ? "内存错误" : result == Z_BUF_ERROR ? "缓冲区错误" : "未知错误") << std::endl; delete[] inputBuffer; delete[] outputBuffer; return false; } // 写入压缩文件 std::ofstream outFile(outputPath, std::ios::binary); if (!outFile.write(reinterpret_cast<char*>(outputBuffer), compressedSize)) { std::cerr << "写入输出文件失败" << std::endl; delete[] inputBuffer; delete[] outputBuffer; return false; } // 清理资源 delete[] inputBuffer; delete[] outputBuffer; outFile.close(); std::cout << "压缩成功!原始大小: " << fileSize << " 字节, 压缩后: " << compressedSize << " 字节" << std::endl; return true; } int main() { if (compressFile("original.txt", "compressed.zlib")) { std::cout << "文件已压缩为 compressed.zlib" << std::endl; } return 0; } ``` ### 关键步骤说明: 1. **头文件包含**:`#include "zlib.h"`(需安装zlib开发库) 2. **缓冲区准备**: - 使用 `compressBound()` 计算最大压缩大小 - 分配输入/输出缓冲区 3. **核心压缩**: - `compress2()` 函数实现压缩(参数:输出缓冲/输入数据/压缩级别) - 压缩级别 `Z_BEST_COMPRESSION` 可替换为 `0`(无压缩)到 `9`(最高压缩) 4. **错误处理**: - 检查返回值 `Z_OK`/`Z_MEM_ERROR`/`Z_BUF_ERROR` 5. **资源清理**: - 释放缓冲区内存 - 关闭文件句柄 ### 编译说明(Linux示例): ```bash g++ -o compressor compressor.cpp -lz ``` ### 注意事项: - 需要安装 zlib 开发包(如 Ubuntu 的 `sudo apt install zlib1g-dev`) - 大文件处理建议使用流式压缩(分块读取) - 解压需使用 `uncompress()` 函数 - 压缩文件无标准扩展名,常用 `.zz` 或 `.zlib`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值