posts - 257, comments - 1336, trackbacks - 63, articles - 8
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

2004年8月7日

        在写完了此Vector非彼Vector这篇随笔之后,带着留下来的一个问题——Java中的Vector与STL中Vector的区别,我开始集中精力去了解STL中的Vector了。原本以为,有大名鼎鼎的好书《C++ Standard Library, The: A Tutorial and Reference》坐镇,进度应该会很挺快的,结果是被一个小问题绊倒,摔得满天星星,到现在还头痛呢。
        大家可以先看这段代码(在VC++6.0上编译执行):

#include <iostream>
#include 
<vector>

using namespace std;

void main() 
{
    vector
<int>
 vec;
    vec.reserve(
5
);
    
    vec[
0= 0;  // 1 

    vec[1= 1;  // 2   

    
if(vec.empty())
    
{
       cout 
<< "The vector is empty!" <<
 endl;
    }

}


        先问大家一个问题,"The vector is empty!"会被打印出来吗?如果将注释中的1、2两行改为:

vec.push_back(0);
vec.push_back(1);

你的答案又会是什么呢?

答案请看:让人头痛的Vector(思索篇)   

posted @ 2004-08-07 16:55 FantasySoft 阅读(9261) | 评论 (16)编辑

       以前在组建乐队的时候,写了唯一的一首歌:
 
                     黑夜与流星                         
            我以为,我是黑夜,眨着寂寞不眠的眼
            我以为,你是流星,来去匆匆闪耀瞬间。
            我只想用我整个身躯拥抱着你,守候着你
            我只想用我的永恒去换你的每一天。
            带着绚丽和温暖,你悄悄擦过我的身边,
            但是我却抓不住我们的永远。

            我以为,我是黑夜,无法拥有最美的蓝天,
            我以为,你是流星,也无法许下自己的心愿。
            我只想用我整个身躯拥抱着你,守候着你
            我只想用我的永恒去换你的每一天。
            不愿看见你的眼泪再次滑落我的脸,
            就让你永远只停留在我的心里面。

posted @ 2004-08-07 01:19 FantasySoft 阅读(378) | 评论 (0)编辑

        所谓泛型,从字面上可以猜想,就是泛化的类型(型别、type)。那么是在什么时候,类型被泛化了呢?我们知道,在编写一个函数的时候,通常都会知道参数(parameter)是什么类型的,很多时候这是理所当然的事情,连类型都不知道,怎么对传入参数进行操作呢?面对这样类似的疑问,C++总会展露出她迷人的笑容,让人消魂。这次,她用温柔的声线告诉我:“我可是能实现可以接受任何适当类型参数的函数哦。
        不会吧,我可没有用Java写过这样的函数哦。嘿嘿,偶还没有勇气去养“老虎”,所以只能这样大惊小怪了。
        其实,我们是可以理解语言支持泛型的,如果为了针对不同的类型去实现相同的行为就要去将代码重复再重复,就真的太笨了,代码重复也正是代码坏味道的一种。在Java中,如ArrayList,Vector都是使用对象数组(Object[])来储存数据的,也就是说这些Collection是基于基础类型(base type)而实现,这样才能使得这个Collection具有通用性,即使如此,ArrayList和Vector也不能存储基本类型(primitive type),因为对象数组的元素根本就不能是int、double这样的基本类型,这样类型是不匹配的。除了这个缺点之外,由于实现这些Collection是基于基础类型的,因此编译器无法进行类型检查,同时也就没有办法进行Collection元素之间关系的处理了。举个简单例子,即使一个ArrayList只是装了Integer类型的数据,编译器都没有办法知道,同时也没有办法直接对这个ArrayList进行操作,从中找出最大值。这就是缺少范型支持的一个大缺陷了。泛型如此重要,而模板函数正是实现泛型函数的基础。

        重温C++的旧梦,我是从标准库开始的,在标准库中,处处都能看到template关键字的身影。Almost all parts of the library are written as templates. Without template support, you can't use the standard library. [1]
        看来还是从最根本的开始了——Template(模板)。在这里,我主要将注意力集中在模板函数上。以下是一个最简单的模板函数:

template <class T> 
inline T 
const& max (T const& a, T const&
 b) 

    
return a < b ?
 b : a; 
}
  

        我们在调用模板函数的时候跟调用一般的函数是没有什么区别的:

#include <iostream>
#include 
<string>
#include 
<vector>
#include 
"max.hpp"

int main() {
    
int i = 42

    std::cout 
<< "max(7,i): " << max(7,i) <<
 std::endl; 

    
double f1 = 3.4

    
double f2 = -6.7

    std::cout 
<< "max(f1,f2): " << max(f1,f2) <<
 std::endl; 

    std::
string s1 = "mathematics"

    std::
string s2 = "math"

    std::cout 
<< "max(s1,s2): " << ::max(s1,s2) <<
 std::endl; 
}

        模板函数之所以能够接受任何类型的参数,其实是在编译的过程中,根据模板使用的情况编译成相应的一般的函数去处理这些不同的参数。譬如例子中有三次调用,就会将模板函数编译成三种版本以处理这三种不同类型的参数了。对于第一个调用max( 7, i ),就是使用了将模板函数中的T替换成int的版本,这也说明了如果这样调用是会无法通过编译的:max ( 7,  3.4 )。
        除此之外,所谓能够接受任何类型的参数,其实也是有限制的。譬如说,max函数中的"<"操作父约束了参数a和b的类型,至少这两个参数能够支持这样的操作才是合法的。

        [1] C++ Standard Library, The: A Tutorial and Reference

posted @ 2004-08-07 01:01 FantasySoft 阅读(714) | 评论 (1)编辑