Effective C++ 2e Item18

聊聊如何保证api接口数据安全? 如何保证api接口数据安全? 阅读详情

类和函数:设计与声明

在程序中声明一个新类将导致产生一种新的类型:类的设计就是类型设计。可能你对类型设计没有太多经验,因为大多数语言没有为你提供实践的机会。在C++中,这却是很基本的特性,不是因为你想去做才可以这么做,而是因为每次你声明一个类的时候实际上就在做,无论你想不想做。

设计一个好的类很具有挑战性,因为设计好的类型很具有挑战性。好的类型具有自然的语法,直观的语义和高效的实现。在C++中,一个糟糕的类的定义是无法实现这些目标的。即使一个类的成员函数的性能也是由这些成员函数的声明和定义决定的。

那么,怎么着手设计高效的类呢?首先,必须清楚你面临的问题。实际上,设计每个类时都会遇到下面的问题,它的答案将影响到你的设计。

·对象将如何被创建和摧毁?它将极大地影响构造函数和析构函数的设计,以及自定义的operator new, operator new[], operator delete, 和operator delete[]。(条款M8描述了这些术语的区别)

·对象初始化和对象赋值有什么不同?答案决定了构造函数和赋值运算符的行为以及它们之间的区别。

·通过值来传递新类型的对象意味着什么?记住,拷贝函数负责对此做出回答。

·新类型的合法值有什么限制?这些限制决定了成员函数(特别是构造函数和赋值运算符)内部的错误检查的种类。它可能还影响到函数抛出的例外的种类以及函数的例外规范(参见条款M14),如果你使用它们的话。

·新类型符合继承关系吗?如果是从已有的类继承而来,那么新类的设计就要受限于这些类,特别是受限于被继承的类是虚拟的还是非虚拟的。如果新类允许被别的类继承,这将影响到函数是否要声明为虚拟的。

·允许哪种类型转换?如果允许类型A的对象隐式转换为类型B的对象,就要在类A中写一个类型转换函数,或者,在类B中写一个可以用单个参数来调用的非explicit构造函数。如果只允许显式转换,就要写函数来执行转换功能,但不用把它们写成类型转换运算符和或单参数的非explicit构造函数。(条款M5讨论了用户自定义转换函数的优点和缺点)

·什么运算符和函数对新类型有意义?答案决定了将要在类接口中声明什么函数。

·哪些运算符和函数要被明确地禁止?它们需要被声明为private。

·谁有权访问新类型的成员?这个问题有助于决定哪些成员是公有的,哪些是保护的,哪些私有的。它还有助于确定哪些类和/或函数必须是友元,以及将一个类嵌套到另一个类中是否有意义。

·新类型的通用性如何?也许你实际上不是在定义一个新的类型,而是在定义一整套的类型。如果是这样,就不要定义一个新类,而要定义一个新的类模板。

这些都是很难回答的问题,所以C++中定义一个高效的类远不是那么简单。但如果做好了,C++中用户自定义的类所产生的类型就会和固定类型几乎没什么区别,如果能达到这样的效果,其价值也就体现出来了。

上面每一个问题如果要详细讨论都可以单独组成一本书。所以后面条款中所介绍的准则决不会面面俱到。但是,它们强调了在设计中一些很重要的注意事项,提醒一些常犯的错误,对设计者常碰到的一些问题提供了解决方案。很多建议对非成员函数和成员函数都适用,所以本章节我也考虑了全局函数和名字空间中的函数的设计和声明。


条款18: 争取使类的接口完整并且最小

类的用户接口是指使用这个类的程序员所能访问得到的接口。典型的接口里只有函数存在,因为在用户接口里放上数据成员会有很多缺点(见条款20)。

哪些函数该放在类的接口里呢?有时这个问题会使你发疯,因为有两个截然不同的目标要你去完成。一方面,设计出来的类要易于理解,易于使用,易于实现。这意味着函数的数量要尽可能地少,每一个函数都完成各自不同的任务。另一方面,类的功能要强大,要方便使用,这意味着要不时增加函数以提供对各种通用功能的支持。你会怎样决定哪些函数该放进类里,哪些不放呢?

试试这个建议:类接口的目标是完整且最小。

一个完整的接口是指那种允许用户做他们想做的任何合理的事情的接口。也就是说,对用户想完成的任何合理的任务,都有一个合理的方法去实现,即使这个方法对用户来说没有所想象的那样方便。相反,一个最小的接口,是指那种函数尽可能少、每两个函数都没有重叠功能的接口。如果能提供一个完整、最小的接口,用户就可以做任何他们想做的事,但类的接口不必再那样复杂。

追求接口的完整看起来很自然,但为什么要使接口最小呢?为什么不让用户做任何他们想做的事,增加更多的函数,使大家都高兴呢?

撇开处世原则方面的因素不谈——牵就你的用户真的正确吗?——充斥着大量函数的类的接口从技术上来说有很多缺点。第一,接口中函数越多,以后的潜在用户就越难理解。他们越难理解,就越不愿意去学该怎么用。一个有10个函数的类好象对大多数人来说都易于使用,但一个有100个函数的类对许多程序员来说都难以驾驭。在扩展类的功能使之尽可能地吸引用户的时候,注意不要去打击用户学习使用它们的积极性。

大的接口还会带来混淆。假设在一个人工智能程序里建立一个支持识别功能的类。其中一个成员函数叫think(想),后来有些人想把函数名叫做ponder(深思),另外还一些人喜欢叫ruminate(沉思)。为了满足所有人的需要,你提供了三个函数,虽然他们做同样的事。那么想想,以后某个使用这个类的用户会怎么想呢?这个用户会面对三个不同的函数,每个函数好象都是做相同的事。真的吗?难道这三个函数有什么微妙的不同,效率上,通用性上,或可靠性上?如果没有不同,为什么会有三个函数?这样的话,这个用户不但不感激你提供的灵活性,还会纳闷你究竟在想(或者深思,或者沉思)些什么?

大的类接口的第二个缺点是难以维护(见条款M32)。含有大量函数的类比含有少量函数的类更难维护和升级,更难以避免重复代码(以及重复的bug),而且难以保持接口的一致性。同时,也难以建立文档。

最后,长的类定义会导致长的头文件。因为程序在每次编译时都要读头文件(见条款34),类的定义太长会导致项目开发过程中浪费大量的编译时间。

概括起来就是说,无端地在接口里增加函数不是没有代价的,所以在增加一个新函数时要仔细考虑:它所带来的方便性(只有在接口完整的前提下才应该考虑增加一个新函数以提供方便性)是否超过它所带来的额外代价,如复杂性,可读性,可维护性和编译时间等。

但太过吝啬也没必要。在最小的接口上增加一些函数有时是合理的。如果一个通用的功能用成员函数实现起来会更高效,这将是把它增加到接口中的好理由。(但,有时不会,参见条款M16)如果增加一个成员函数使得类易于使用,或者可以防止用户错误,也都是把它加入到接口中的有力依据。

看一个具体的例子:一个类模板,实现了用户自定义下标上下限的数组功能,另外提供上下限检查选项。模板的开头部分如下所示:

template<class T>
class Array {
public:
  enum BoundsCheckingStatus {NO_CHECK_BOUNDS = 0,
                             CHECK_BOUNDS = 1};

  Array(int lowBound, int highBound,
       BoundsCheckingStatus check = NO_CHECK_BOUNDS);

  Array(const Array& rhs);

  ~Array();

  Array& operator=(const Array& rhs);

private:
  int lBound, hBound;         // 下限, 上限

  vector<T> data;             // 数组内容; 关于vector,
                              // 请参见条款49

  BoundsCheckingStatus checkingBounds;
};

目前为止声明的成员函数是基本上不用想(或深思,沉思)就该声明的。一个允许用户确定每个数组上下限的构造函数,一个拷贝构造函数,一个赋值运算符和一个析构函数。析构函数被声明为非虚拟的,意味着这个类将不作为基类使用(见条款14)。

对于赋值运算符的声明,第一眼看上去会觉得目的不那么明确。毕竟,C++中固定类型的数组是不允许赋值的,所以好象也应该不允许Array对象赋值(参见条款27)。但另一方面,数组似的vector模板(存在于标准库——参见条款49)允许vector对象间赋值。在本例中,决定遵循vector的规定,正如下面将会看到的,这个决定将影响到类的接口的其他部分。

老的C程序员看到这个接口会被吓退:怎么竟然不支持固定大小的数组声明?很容易增加一个构造函数来实现啊:

Array(int size,
      BoundsCheckingStatus check = NO_CHECK_BOUNDS);

但这就不能成为最小接口了,因为带上下限参数的那个构造函数可以完成同样的事。尽管如此,出于某些目的去迎合那些老程序员们的需要也可能是明智的,特别是出于和基本语言(C语言)一致的考虑。

还需要哪些函数?对于一个完整的接口来说当然还需要对数组的索引:

// 返回可以读/写的元素
T& operator[](int index);

// 返回只读元素
const T& operator[](int index) const;

通过两次声明同一个函数,一次带const一次没有const,就提供了对const和非const Array对象的支持。返回值不同很重要,条款21对此进行了说明。

现在,Array模板支持构造函数,析构函数,传值,赋值,索引,你可能想到这已经是一个完整的接口了。但再看清楚一些。假如一个用户想遍历一个整数数组,打印其中的每一个元素,如下所示:

Array<int> a(10, 20);      // 下标上下限为:10到20

...

for (int i = a的下标下限; i <= a的下标上限; ++i)
  cout << "a[" << i << "] = " << a[i] << '/n';

用户怎么得到a的下标上下限呢?答案取决于Array对象的赋值操作做了些什么,即在Array::operator=里做了什么。特别是,如果赋值操作可以改变Array对象的上下限,就必须提供一个返回当前上下限值的成员函数,因为用户无法总能在程序的某个地方推出上下限值是多少。比如上面的例子,a是在被定义后、用于循环前的时间段里被赋值的,用户在循环语句中就无法知道a当前的上下限值。

如果Array对象的上下限值在赋值时不能改变,那它在a被定义时就固定下来了,用户就可能有办法(虽然很麻烦)对其进行跟踪。这种情况下,提供一个函数返回当前上下限值是很方便,但接口就不能做到最小。

继续前面的赋值操作可以改变对象上下限的假设,上下限函数可以这样声明:

int lowBound() const;
int highBound() const;

因为这两个函数不对它们所在的对象进行任何修改操作,而且为遵循“能用const就尽量用const”的原则(见条款21),它们被声明为const成员函数。有了这两个函数,循环语句可以象下面这样写:

for (int i = a.lowBound(); i <= a.highBound(); ++i)
  cout << "a[" << i << "] = " << a[i] << '/n';

当然,要使这样一个操作类型T的对象数组的循环语句工作,还要为类型T的对象定义一个operator<<函数。(说得不太准确。应该是,必须有一个类型T的operator<<,或,T可以隐式转换(见条款M5)成的其它类型的operator<<)

一些人会争论,Array类应该提供一个函数以返回Array对象里元素的数量。元素的数量可以简单地得到:highBound()-lowBound()+1,所以这个函数不是那么真的必要。但考虑到很多人经常忘了"+1",增加这个函数也不是坏主意。

还有一些其他函数可以加到类里,包括那些输入输出方面的操作,还有各种关系运算符(例如,<, >, ==, 等)。但这些函数都不是最小接口的一部分,因为它们都可以通过包含operator[]调用的循环来实现。

说到象operator<<, operator>>这样的函数以及关系运算符,条款19解释了为什么它们经常用非成员的友元函数而不用成员函数来实现。另外,不要忘记友元函数在所有实际应用中都是类的接口的一部分。这意味着友元函数影响着类的接口的完整性和最小性。

C++ Builder 6 源代码深度解析:从经典VCL框架到现代工程实践 在桌面应用开发领域,快速应用开发(RAD)框架通过可视化组件和事件驱动编程,极大提升了软件构建效率。其核心原理在于将界面设计与业务逻辑分离,通过封装底层系统API(如Windows消息机制和图形设备接口)为可重用的控件库。这种范式不仅加速了原型开发,更在企业级应用、工控系统和数据库前端等场景中证明了其工程价值。以经典的VCL框架为例,它代表了RAD理念在C++环境下的高峰实践。本文聚焦于对C++ Builder 6(BCB6)这一特定历史版本所附带的示例源代码进行体系化研究,旨在挖掘其中关于**数据库访问层 阅读详情

相关推荐

C++Builder 5项目实战:从经典VCL开发到现代化重构指南

可视化组件库(VCL)作为高效的桌面应用开发框架,通过基于属性的组件化模型,实现了界面快速构建与业务逻辑的分离。其核心原理在于将UI元素封装为独立对象,通过事件驱动机制响应用户交互,在提升开发效率的同时,保持了底层C++代码的可控性。这一技术价值体现在能够大幅缩短从原型到产品的开发周期,特别适合需要快速迭代的工业控制、数据采集等场景。本文以经典著作《C++Builder 5编程实战》中的项目为例,深入探讨如何将基于BDE、Indy等传统组件的遗留系统,迁移至FireDAC、GDI+等现代技术栈,并解决多线程

weixin_30596023的博客 401

接口完整性思路及解决方法

银行接口字段校验 内容: 1.字段非空校验。 2.字段是否符合接口文档规定类型或指定值。 3.判断数据是否是重复的。 作用: 1.防止垃圾数据进入业务系统。 2.接入银行较多,方便银行自己查找原因,减少不必要的工作。 正则表达式: 1.判断是否是指定的值。 ...

sun_boss_nubmerone的博客 1214

C++Builder 6 核心架构与实战开发指南:从VCL框架到数据库应用

快速应用程序开发(RAD)是一种通过可视化工具和组件库提升软件构建效率的经典范式,其核心原理在于将界面设计与业务逻辑分离,通过事件驱动模型简化开发流程。这一理念在桌面应用开发中具有重要技术价值,尤其适用于需要快速构建图形用户界面(GUI)的工业控制、数据采集和管理信息系统等场景。C++Builder 6作为该范式的代表性工具,其内置的VCL(可视化组件库)框架和高效的C++编译器,使得开发者能够通过拖拽组件和编写事件处理代码,快速实现功能完备的应用程序。本文聚焦于C++Builder 6的**VCL框架**

weixin_34343000的博客 382

接口测试的小知识(一)

接口测试的小知识,包含,接口测试的含义,目的,原理和如何进行接口测试等等。

Dreamer_HUI的博客 943

数据对接中的安全性保证及接口设计

主要分为三个方面: 1. 数据传输加密 目前普遍采用SSL协议中相关算法进行传输层的加密,通常是对称的摘要算法(配合证书通过https进行数据对接),或者使用VPN(IPSEC VPN、SSL VPN、MPLS VPN)进行传输甚至专用电路MSTP。 2. 身份认证 目前普遍采用数字证书技术进行身份认证,数字证书具体又可以分为第三方证书和自签名的证书。认证方法又可以分为单向认证和双

数据的启示 7523

群控和云控的区别?

一直以来云控都在和群控争夺市场,许多云控开始吹的漫无边际,那么云控和群控是什么?二者又有什么区别呢? 1、云控比群控控制更多的手机? 云控最能意淫自己的是一台电脑可以控制100台以上手机,以为自己多牛逼,其实自己是井底之蛙,根本不了解群控这个行业,毕竟这个行业很有深度。 现在群控有传统的群控,代表品牌有奥创,还有分控形式的群控,代表品牌有通路云,这里说的两个品牌都是有自己核心技术的。单说分控形式的通路云,不仅可以一台电脑可以控制多台手机,也可以多台电脑控制多台手机,更可以一台电脑控制100部以

jinchan074的博客 3749

接口测试理论

了解接口测试https://www.cnblogs.com/houzhizhe/p/6825457.html 什么是接口测试 测试人员通常所说的“接口测试”是针对系统各组件之间接口的一种测试,它属于功能测试。接口能测出普通界面操作难以发现的问题。如,我们都知道系统是由前端后端组成,一些数据在前端做了校验,后端同样也需要校验才能保证安全,界面操作显然只能检查到前端校验这一层,只有直接面对前后端之间的...

少年掉发吧 765

2026年信创系统技术应用专业人才培养基地建设方案(高职、信创新专业、人才培养、专业代码:510221)

响应国家信创产业战略及教育部新增“信创系统技术应用”专业(代码510221)的部署,联合麒麟软件、华为鸿蒙等领军企业,建设高水平信创人才培养基地。方案基于国家政策导向(如2027年央企全面国产化替代目标)和行业人才缺口(2025年缺口超80万人),提出以“产教融合、创新驱动”为核心,构建集教学、实训、认证于一体的综合性培养体系。 建设内容涵盖五大方向: 专业规划:分三阶段(2025-2030年)推进专业申报、课程开发与区域辐射,最终建成区域性信创技术创新平台。 课程体系:围绕运维、云计算、数据库、适配

啊碧根果的博客 1600

最小接口

原文:MinimalInterface    设计            Bliki 索引所谓最小接口,其设计风格与人本接口形成鲜明对照,它背后的主旨是设计一套API不仅能满足用户完成所有操作的需求,还要把这种能力积聚到一个最精简的方法集合上。(两者的区别请参考人本接口里的例子。)拿人本接口里的例子“Ruby-Array VS Java-List”来说,既然List已经有了取索引位置处元素

Martin Fowler's Bliki 中文版 1万+

解密UFS Explorer:Drobo BeyondRAID数据恢复实战指南

本文详细介绍了使用UFS Explorer Professional Recovery软件中的Drobo BeyondRAID助手进行数据恢复的完整实战流程。当Drobo设备因BeyondRAID配置信息丢失而无法访问时,该工具能安全、只读地扫描硬盘,虚拟重建存储池,帮助用户找回宝贵数据。指南涵盖了从前期准备、硬盘选择、配置扫描到数据安全导出的每一步关键操作与常见问题解决方案。

weixin_29219539的博客 270

接口压力测试数据的完整性校验

近几年都在做接口运维工作,接口数据在压力测试的数据校验方法,我想到几个:1、校验数据完整性:发送方数据 (最后一个字段为前面全部字段的总和)字段1字段2字段3字段4字段5aaabbbcccdddaaacccbbbddd接收方程序数据校验,把前4个字段都加上,然后同第5个字段比较,完全一致为正确。2、校验数据顺序一致性:发送方数据(某一个字段用流水号,增量为1)接收方程序从第一条开始取出流水号,加1...

刘欣的优快云博客 2494

Tessent MBIST SDC

主要是两个PROC,tessent_constrain_${design_name}_mentor_ijtag_non_modal和tessent_constrain_${design_name}_mentor_memory_bist_modal。其中,Memory/MBIST controller/MEM Interface可以从func_clk_1来(用func_clk_1和func_clk_2的高频时钟),如图中红色线。其中,SIB和BAP用ijtag_tck的clock,如图绿色线。

po_poo的博客 1989

系统接口规范以及常见的接口技术概述和比较

系统接口规范以及常见的接口技术概述和比较2009-11-27 11:00<br />一、基本要求:<br /><br />为了保证系统的完整性和健壮性,系统接口应满足下列基本要求:<br />1、接口应实现对外部系统的接入提供企业级的支持,在系统的高并发和大容量的基础上提供安全可靠的接入;<br />2、提供完善的信息安全机制,以实现对信息的全面保护,保证系统的正常运行,应防止大量访问,以及大量占用资源的情况发生,保证系统的健壮性;<br />3、提供有效的系统的可监控机制,使得接口的运行情况可监控,便于及

nhpyliner的专栏 1万+

AI Agent开发第84课-paddleocr-vl全网唯一最全本地化布署教程

本文详解 PaddleOCR-VL 本地化布署全过程,指出为何在真实生产环境中 PaddleOCR-VL 更稳定、更易部署、更贴近工程落地。同时还会详细比较与 DeepSeek-OCR 的核心差异,为全网独家介绍paddleocr-vl的本地部署实战指南。

打造全国最全的AI Agent开发知识领域的博客 5969

传统(经典)粒子群算法(PSO)解决单目标优化问题

智能算法:粒子群算法(particle swarm optimizer)—PSO %原理:(1)种群初始化–N(种群数)–D(个体数)–x(i)(粒子位置)–v(i)(粒子速度) % (2)计算每个粒子的适应度值–而适应度值需要选择适应度函数 % (3)对于每个粒子,使用它的适应度值fit[i]和个体的极值pbest(i)进行比较,如果fit[i]>pbest(i),则pbest(i)=fit[i] % (4)同理,对每个粒子用它的适应值与全局极值进行比较,如果比它大,则

weixin_51631044的博客 1295

一文说完云控和群控的技术发展历程

我们先说好,这是技术发展历程的介绍,哥们不碰黑产。

qq_59122359的博客 3931

Windows配置CA证书颁发机构+NPS-DCServer

Windows配置证书颁发机构+NPS-DCServer

新时代先锋的博客 3万+

接口隔离原则(最小接口隔离原则)

基本概念: 接口实现类不应该依赖它不需要的接口,即要保证最小接口原则。 接口隔离要做的事: 如果一个类通过一个接口的实现类,只使用了部分方法,则应当将接口拆分(按照最小接口原则)拆成多个接口 举例: 如下有一个接口 Interface1 有5个抽象方法,其中B、D都是Interface1的实现类 而A需要使用B实现的operation1-3方法,C则需要使...

诗水人间 14万+

大模型安全研究论文整理 2026年版

知乎博主小红书博主GitHub数据集参考: 大模型越狱指令 (harmful questions) 数据集整理会思考的大模型更不听话,我的豆包失控了…让QwQ思考模型-不思考的小技巧qwen3的致命幻觉!大模型微调所有大模型都在讨好人类不要思考过程,推理模型能力能够更强丨UC伯克利等最新研究o3/o4-mini幻觉暴增2-3倍!OpenAI官方承认暂无法解释原因UC伯克利:让推理模型少思考,准确率反而更高了!一句话让DeepSeek思考停不下来,北大团队:这是针对AI的DDoS攻击慢思考准确率反降30%!普

CSPhD-winston的博客 2044

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

这些年使用群控、云控的心得体会

很多人听说过“群控”吧,就光这个词就搞得牛逼哄哄的,你应该听过,但估计你听说过的印象也只是停留在这个词或者网上流传的一张图片画面上吧,因为你也没用过...我是2014年开始接触到群控的,那些年主要是做淘宝客,通过群控系统在QQ上建立很多2000多个淘宝购物优惠券群,每天去阿里妈妈搜寻低价有吸引力的商品,通过QQ群发送,每天少的话有300-500收入,多的一天几千也很正常。那个时候竞争不是那么激烈,...

weixin_33918114的博客 6393

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

什么是接口技术

1. 什么是接口? 接口就是微处理器CPU与外部世界的连接部件,是CPU与外界进行信息交换的中转站。 2. 为什么要在CPU与外设之间设置接口? 在CPU与外设之间设置接口主要有4个原因: (1) CPU与外设二者的信号不兼容,包括信号线的功能定义、逻辑定义和时序关系 (2) CPU与外设的速度不匹配,CPU的速度快,外设的速度慢 (3) 若不通过接口,而由CPU直接对外设的操作实施控...

mmdev 2986

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

设计原则之接口隔离原则

接口隔离原则 定义: 客户端不应该依赖它不需要的接口 类间的依赖关小应该建立在最小的接口上 什么是接口? 1.实例接口: Person zhangsan = new Person(); 类Person就是zhangsan的实例接口。 2.类接口,就是通常意义上,用interface关键字定义的接口。 解释: 根据接口隔离原则的定义:事实上就是建立单一接口,不要建立臃肿的接口。接口尽量细化,同时接口中的方法尽量少。 接口隔离原则和单一职责原则 接口隔离原则讲的是不论是实例接口也好,还是类接口也好,都要做

Lucky_xiang 331

看了一下Martin Fowler谈的人本接口和最小接口

有点意思,学到些东西。BTW:好像我自己写的都是一种这样的接口——按我自已的习惯用法得出的最小接口+所有可以inline的方便方法也算是人本接口了,哇哈哈 

sonicfly的专栏 475

神作还是噱头?群控、云控、智控到底哪个好

近半年,网络上突然出现了一款新的电脑控制手机软件,各种好各种优势,传说中的智控,真有传说中的那么神吗?笔者长期使用过群控和云控。不如,我们来看看到底是不是这么厉害? 这是某智控软件列出的自己的优势,不如我们来一一击破。 1、外观:一体机确实小巧玲珑,说实话,咱们都是挣钱的,并不都是精致的猪猪男孩女孩。只要性价比高,长的好看与否,并不重要; 2、结构,列出了所需要的东西,但优势是什么...

lemon5814的博客 5489
上一篇: Effective C++ 2e Item17
下一篇: Effective C++ 2e Item19
lostmouse
博客等级 码龄26年 22粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值