MyMSDN

MyMSDN记录开发新知道

C++ notes (4)

31、动态空间的释放(P119)

动态空间的释放使用delete [] pia;(其中pia为指向动态分配的数组的第一个元素的指针)。在关键字delete和指针之间的方括号对是必不可少的:它告诉编译器该指针指向的是自由存储区中的数组,而并非单个对象。

如果遗漏了空方括号对,这是一个编译器无法发现的错误,将导致程序在运行时出错。

使用std::string后则会自动进行释放,无需delete!

32、c_str返回的数组并不保证一定是有效的……

std::string st1("I am a string object!");
//error C2440: “初始化”: 无法从“const char *”转换为“char *”
//char *str = st1.c_str();
const char *cstr = st1.c_str();
std::cout<<cstr<<std::endl;

c_str返回的数组并不保证一定是有效的,接下来对st1的操作有可能会改变st1的值,使刚才返回的数组失效。如程序需要持续访问该数据,则应该复制c_str函数返回的数组。

33、指向函数的指针

详见《指向函数的指针的一点理解

34、容器初始化

在大多数的程序中,使用默认构造函数能达到最佳运行时性能,并且使容器更容易使用。

35、容器头文件

#include <vector>

#include <list>

#include <deque> //双端队列“double-ended queue”,发音为“deck”

标准库定义了以上三种顺序容器类型。

36、容器的容器

必须用空格隔开两个相邻的>符号,以示这是两个分开的符号,否则,系统会认为>>是单个符号,为右移操作符,并导致编译时错误。

int m, n;
m = 5;
n = 3;

cout << "Print a line!" << endl;
vector<string> lines(n, " I_am_a_PC_! ");
for (vector<string>::iterator siter = lines.begin(); siter != lines.end(); ++siter) {
    cout << *siter;
}
cout << endl;

cout << "Print a paragraph!" << endl;
vector<vector<string> > paragraph(m, lines);
for (vector<vector<string> >::iterator piter = paragraph.begin(); piter
        != paragraph.end(); ++piter) {
    for (vector<string>::iterator siter = (*piter).begin(); siter
            != (*piter).end(); ++siter) {
        cout << *siter << ends;
    }
    cout << endl;
}

37、迭代器范围(P269)

C++定义的容器类型中,只有vector和deque容器提供下面两种重要的运算集合:迭代器算术运算,以及使用除了==和!=之外的关系操作符来比较两个迭代器(==和!=这两种关系运算适用于所有容器)。

list容器的迭代器既不支持算术运算(减法或加法),也不支持关系运算(<=,<,>=,>)它只提供前置和后置的自增、自减以及相同(不等)运算。

38、容器元素都是副本

在容器中添加元素时,系统是将元素值复制到容器里的。类似地,使用一段元素初始化新容器时,新容器存放的是原始元素的副本。被复制的原始值与新容器中的元素各不相关,此后容器内元素值发生变化时,被复制的原值不会受到影响,反之亦然。

39、下标操作和.at(n)的区别

vector<string> svec; //empty vector;

cout << svec[0]; //run-time error:There are no elements in svec!

cout << svec.at(0); //throws out_of_range exception

40、容器的赋值(P283)

assign操作首先删除容器中所有的元素,然后将其参数所指定的新元素插入到该容器中。与复制容器元素的构造函数一样,如果两个容器类型相同,其元素类型也相同,就可以使用赋值操作符(=)将一个容器赋值给另一个容器。如果在不同(或相同)类型的容器内,元素类型不相同但是相互兼容,则其赋值运算必须使用assign函数。例如,可通过assign操作实现将vector容器中一段char*类型的元素赋给string类型的list容器。

由于assign操作首先删除容器中原来存储的所有元素,因此,传递给assign函数的迭代器不能指向调用该函数的容器内的元素。

posted on 2009-02-05 03:48 volnet 阅读(1947) 评论(5)  编辑 收藏 引用 所属分类: C++ Primer 学习笔记

评论

# re: C++ notes (4) 2009-02-05 09:00 路人丁

“c_str返回的数组并不保证一定是有效的”
--- 你的意思其实是“……不保证一定是永远有效的”,不过这也是个显而易见的废话。  回复  更多评论   

# re: C++ notes (4) 2009-02-05 09:02 路人丁

为什么写成
const char *cstr = st1.c_str();
std::cout<<cstr<<std::endl;
而不是
std::cout << st1.c_str() << std::endl;


糟糕的,和自以为是的恶习,是产生错误最大的根源。  回复  更多评论   

# re: C++ notes (4) 2009-02-05 09:21 梦在天涯

使用std::string后则会自动进行释放,无需delete!

啥意思啊,一般的对象都是在栈上,自动分配和释放!不需要new和delete!  回复  更多评论   

# re: C++ notes (4) 2009-02-06 09:57 路人丙

string对象一般分配在栈上,但是它内部用char *指针指向堆内存。其实它有new和delete的调用,只不过我们看不到而已  回复  更多评论   

# re: C++ notes (4) 2009-02-06 15:01 volnet

@路人丁
----------------------------
const char *cstr = st1.c_str();
std::cout<<cstr<<std::endl;
而不是
std::cout << st1.c_str() << std::endl;

----------------------------
这么写当然不是为了输出,只是为了说明c_str的功能,输出何必这样写呢?

  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


特殊功能