谈谈960

选用960,其实很简单,因为960能够被很多数整除,同时又很接近1024,因此很多网站选用了这个宽度。

我在960的秘密一文中,只是想从数学的角度上指出对栅格系统来说,960是个很灵活的宽度而已。这只是一个引子,想激发大家对栅格系统的兴趣,之后的文章才是重点。

我的数学分析

在将960分解质因数后,我最初的结论确实有不妥之处。这点小奎指出来了,720比960的约数更多,还有1440的约数也很多。从数学上,可以简化为以下问题:

W = 2^m * 3^n * 5 N(W) = (m + 1) * (n + 1) * 2 - 2

mn是整数,现在要使得N(W)尽量大,同时W的值最接近1024. 简单分析质因数可以得到:

... N(480) = N(2^5 * 3 * 5) = 22 N(960) = N(2^6 * 3 * 5) = 26 N(1920) = N(2^7 * 3 * 5) = 30 ... N(360) = N(2^3 * 3^2 * 5) = 22 N(720) = N(2^4 * 3^2 * 5) = 28 N(1440) = N(2^5 * 3^2 * 5) = 34 ...

就这两个系列的的N值最大(稍加分析,能够比较明显地“看”出来,我相信数学系的学生能严格证明)。

很明显,上面最接近1024的就是960.

国外同行的依据

960不是新鲜玩意,国外同行们已经有过很多讨论,比如:Optimal width for 1024px resolution?, 作者选用960的原因是:

I’ve been using 960 for some time now, as it’s slightly smaller than full width, and it’s divisible by 3, 4, 5, 6, 8, 10, 12, 15, and 16 (imagine the grid possibilities). I’d love to hear what all of you are wrestling with.

再来看看960.gs作者的解释:

All modern monitors support at least 1024 × 768 pixel resolution. 960 is divisible by 2, 3, 4, 5, 6, 8, 10, 12, 15, 16, 20, 24, 30, 32, 40, 48, 60, 64, 80, 96, 120, 160, 192, 240, 320 and 480. This makes it a highly flexible base number to work with.

关于苹果系统下浏览器的默认宽度为960,国外也早有人谈及,看看这个ppt:Grids Are Good

一个有意思的巧合

上周去阿里中文站交流CMS系统的设计,中文站选用了960的宽度。他们调研了很多显示设备,发现320是很多显示设备屏幕的最小单位。因此在Web浏览器上,选用了3个320组成的960布局。这个思路蛮有意思。

关于10像素的间距

选用10px的理由非常简单:写CSS时,比较容易计算各种padding和margin. 淘宝的设计有个潜规则:间距最好都是5px的倍数。5的倍数容易计算,对人友好。Blueprint的设计中,也是把间距定位10px, 类似的例子有很多。就这么简单。

值得一提的是,阿里中文站采用了8px, 原因是8是2的立方,计算机在渲染时,能减少性能开支。不过这个性能影响实在太小了。在软件工程中,人的成本是最大的,感觉对计算机友好不如对人更友好。

关于Grid的翻译

个人觉得“网格”太偏设计领域,而且“网格”的外延很多,不容易让读者立刻领悟要表达的意思。不如“栅格”,一看就很明了。当然,每个译者都可以保留自己的意见,就如“优雅降级”和“平稳退化”一样,存在的不一定是最好的。既然是翻译,就应该有自己的思考和选择。

关于腾讯兄弟的数学证明

w = x * n + (n - 1) * y

上面这个公式和我说的是一样的,x是我说的c, y是槽距g, 对于950, 我的公式是:

W = c * N + g * (N - 1)

至于后面的,

w=z*Math.floor(n/m)+(Math.floor(n/m)-(n%m-1))*y+x*(n%m)

实在不敢苟同。何必引入z来让问题复杂化?小模块划分好了,大模块也就有了。本质上都是穷举,没必要这样折腾。

其它的,比如黄金分割,不想说什么。如果腾讯兄弟认为1px的栅格有意义,我实在佩服。

很重要的一点

栅格并不会限制设计师们的设计,这个在《超越CSS》一书里有很好的阐述和例子。若认为栅格化后,设计师们只能定定颜色、画画小图,实在让我汗流浃背无语凝噎。

栅格化对前端开发工程师更是一种解放,从每天的重复性劳动中解脱出来,多些时间来研究新应用,无论对公司还是对个人都是好的。

最后,提前公布下工具

我不会Photoshop, 原文章中的那些图,其实都是用自己写的一个小工具生成的。放在线上好久了,只是想着等完善后再公布:

http://lifesinger.org/lab/2008/grid_design_tool.html

这个工具借鉴了老外的 Grid Designer 2. 功能如下:

  1. 可以测试各种蛋糕的切法^o^
  2. 公式中,带灰色小箭头的表示是计算值,可以在三种计算值之间切换
  3. 注意那个Add Box按钮,添加的Box,可以拖动,鼠标放到边框附近,还可以调整大小
  4. 还有一些方便截图的小功能,折腾折腾应该就会用

最后,本文不欢迎任何侮辱性的留言评论。我非常期望国内的前端开发工程师们能向国外的同行们学习:开放真诚地讨论问题,互助学习、共同进步。

<think>好的,我现在要回答关于C++中多态的问题。首先,我需要回顾多态的基本概念和它在C++中的实现方式。多态是面向对象编程的三大特性之一,另外两个是封装和继承。多态允许不同类的对象对同一消息做出响应,即同一个方法调用根据对象的不同类型有不同的行为。 接下来,我需要确定用户的问题“谈谈多态”具体需要哪些方面的内容。用户可能希望了解多态的定义、实现方式、虚函数的作用、动态绑定以及实际应用例子等。因此,我需要覆盖这些方面,确保回答全面。 首先,解释多态的基本概念,分为编译时多态和运行时多态。编译时多态包括函数重载和运算符重载,而运行时多态则通过虚函数和继承实现。这里需要详细说明虚函数的作用机制,比如虚函数表(vtable)和虚函数指针(vptr),以及动态绑定的过程。 然后,给出一个具体的代码示例,展示如何通过基类指针调用派生类的重写函数。代码中需要基类声明虚函数,派生类覆盖该虚函数,然后通过基类指针指向派生类对象,调用虚函数时实际执行的是派生类的方法。这能直观地展示运行时多态的效果。 同时,需要提到纯虚函数和抽象基类,说明它们如何强制派生类实现特定接口,从而支持多态。此外,虚析构函数的重要性也不可忽视,确保通过基类指针删除派生类对象时能正确调用派生类的析构函数,避免内存泄漏。 在解释过程中,要确保术语准确,比如区分覆盖(override)和隐藏(hide),说明override关键字的作用,以及C++11之后的相关特性。同时,要指出多态带来的好处,如代码的可扩展性和可维护性,以及可能的性能开销,比如虚函数调用需要通过虚表间接寻址,可能影响性能。 最后,根据用户的指示,生成四个相关问题,这些问题应该涵盖多态的不同方面,如定义、虚函数、纯虚函数、虚析构函数的原因等,确保问题之间有逻辑关联,帮助用户进一步深入学习。 现在需要检查是否有遗漏的关键点,例如动态绑定与静态绑定的区别,或者多态在实际项目中的应用场景。确保回答结构清晰,先总述多态,再分点详细解释,最后代码示例和相关问题。避免使用过于复杂的术语,保持解释简洁明了,适合不同层次的学习者理解。</think><< 多态是面向对象编程中允许不同对象对同一操作表现出不同行为的特性。在C++中主要通过虚函数和继承实现,分为编译时多态(静态绑定)和运行时多态(动态绑定)。 ### 多态的实现方式: 1. **虚函数(Virtual Functions)** 在基类中用 `virtual` 关键字声明函数,派生类可以重写(override)该函数。通过基类指针或引用调用时,会根据实际对象类型执行对应的函数。 ```cpp class Animal { public: virtual void speak() { cout << "Animal sound" << endl; } }; class Dog : public Animal { public: void speak() override { cout << "Woof!" << endl; } // 重写基类虚函数 }; ``` 2. **纯虚函数(Pure Virtual Functions)** 基类声明未实现的虚函数(用 `= 0` 标记),强制派生类必须实现。包含纯虚函数的类称为抽象类,不能实例化。 ```cpp class Shape { public: virtual double area() = 0; // 纯虚函数 }; ``` 3. **动态绑定(Dynamic Binding)** 运行时根据对象类型确定调用哪个函数。通过虚函数表(vtable)和虚指针(vptr)实现。 4. **虚析构函数(Virtual Destructor)** 确保通过基类指针删除派生类对象时,能正确调用派生类的析构函数: ```cpp class Base { public: virtual ~Base() {} // 虚析构函数 }; class Derived : public Base { public: ~Derived() { /* 清理派生类资源 */ } }; ``` ### 示例代码: ```cpp #include <iostream> using namespace std; class Animal { public: virtual void speak() { cout << "Animal sound" << endl; } virtual ~Animal() = default; // 虚析构函数 }; class Dog : public Animal { public: void speak() override { cout << "Woof!" << endl; } }; class Cat : public Animal { public: void speak() override { cout << "Meow!" << endl; } }; int main() { Animal* animals[] = {new Dog(), new Cat()}; for (auto* animal : animals) { animal->speak(); // 输出 Woof! Meow! delete animal; } return 0; } ``` ### 关键点: - **编译时多态**:如函数重载、模板,在编译期确定调用。 - **运行时多态**:通过虚函数动态绑定,需运行时类型信息(RTTI)。 - **override关键字**(C++11):明确表示重写,避免意外隐藏(hide)基类函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值