Chinaunix首页 | 论坛 | 博客
  • 博客访问: 20816
  • 博文数量: 14
  • 博客积分: 325
  • 博客等级: 一等列兵
  • 技术积分: 155
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-13 10:46
文章分类

全部博文(14)

文章存档

2012年(14)

我的朋友
最近访客

分类: C/C++

2012-09-12 20:59:34

每个C++程序必须含有main函数,且main函数是唯一被操作系统显式调用的函数。标准的main只能是以下2中形式之一:
int main();
int main(int argc, const char *argv[]);
 
在UNIX系统中,可以通过“$?变量查看最近一个main函数执行的返回值。
在Windows系统中,可以通过%ERRORLEVEL%”变量查看最近一个main函数执行的返回值。
 
 
std::cin 标准输入。
std::cout 标准输出。
std::cerr 标准错误输出。
std::clog 标准日志输出。
 
iostream中的std::endl是一个操纵符,将它写入到输出流中,具有输出换行的效果,并刷新与设备相关联的输出缓冲区。通过刷新缓冲区,用户可以立即看到写入到流中的输出内容。
 
iostream库定义了接受全部内置类型的输入输出操作符版本。
 
当使用istream对象为条件时,其实是测试流的状态。若流是有效的,那么测试的结果为true。若遇到文件结束符(eof)或者其它无效输入时,则istream对象是无效的。如:

  1. int number;
  2. while(std::cin >> number)
  3. {
  4. }

在Unix系统中,通常用ctrl-d来输入文件结束符,而在Windows系统中,通常用control-z
 
 
 
模板(template)是针对“一个或多个尚未明确的类型”所编写的类型或方法。模板类型可以是包括基本类型和高级类型的任何类型,只要其提供template定义式内所用到操作
 
使用template时,可以显式地或隐式地将类型当作参数来传递。如:

  1. template <class T, class U>
  2. inline const T& max(const T &a, const U &b)
  3. {
  4.     return a < b ? b : a;
  5. }
隐式调用 max(1, 2) 相当于显式调用 max(1, 2)
 
template并非一次编译便生成适合所有类型的代码,而是针对被使用的某个(或某组)类型进行编译。那么在处理template时,你需要先提供它的某个实作品,然后才能调用,所以需要在头文件中以inline实现模板方法,虽然标准引入了一个template compilation model(模板编译模型)和一个关键字export来分离模板的声明和定义,但目前绝大多数编译器都没有实现这一特性。
 
不同模板参数的类型是完全不相关的类型。
 
模板类可以有默认的模板参数,且默认的模板参数可根据前面的参数而定义。而模板方法/函数不能指定默认模板参数。如:

  1. template <class T, class U=vector<T> > /* 两个">"之间必须有空格,否则">>"会被解读为位移运算符 */
  2. class MyClass;

typename关键字被用来做类型之前的标识符号,若没有typename关键字,模板类型内的任何标识符都被视为一个值而非一个类型,如:

  1. template <class T>
  2. class MyClass {
  3.     typename T::SubType *ptr; /* 若没有typename关键字,SubType会被当成T类型的static成员。这条语句就会被解释为SubType与ptr的乘积。 */
  4. };
 

C++中没有内部类,只有嵌套类:
 
  1. class Q {
  2.     typedef int SubType;
  3.     class SubType2 {
  4.     };
  5.     ...
  6. };

嵌套类也可以是模板类,它可以访问外层类的静态成员。
 
模板类中拷贝构造方法默认赋值操作符的形参类型必须要和模板的类型精确匹配:

  1. template<class T >
  2. class MyClass {
  3. public:

  4.     // 拷贝构造方法
  5.     MyClass(const MyClass &a) {
  6.     }

  7.     // 不是拷贝构造方法,仅是一个普通的有参构造方法
  8.     template <class U>
  9.     MyClass(const MyClass<U> &a) {
  10.     }

  11.     // 默认的赋值操作符
  12.     MyClass & operator= (const MyClass &c) {
  13.         return *this;
  14.     }

  15.     // 不是默认的赋值操作符,仅是一个普通的赋值操作符.
  16.     template <class U>
  17.     MyClass & operator= (const MyClass<U> &c) {
  18.         return *this;
  19.     }

  20.     . . .
  21. };

基本类型的初始化:

  1. int i1, i2(), i3(23), i4(int()), i5=int();
  2. // i1为随机数,i2等于1,i3等于23,i4等于1,i5等于0

  3. T x = T(); // 确保x被初始化为0,所以拷贝构造方法不应添加explict关键字!

 
 
抛出异常会执行堆栈辗转开解过程,也就是说它将使退离任何函数区段时的行为像以return语句返回一样,局部对象的析构方法都会被调用,这个过程一直持续直到退出main函数或某个try-catch语句捕捉并处理了该异常为止。
 
异常对象可以是任何基本类型和高级类型。
 
你可以使用异常规格来指明某个方法可能抛出哪些异常。若声明一个空的异常规格,则表示该方法不会抛出任何异常,如:

  1. void fun1() throw(std::bad_alloc);
  2. void fun2() throw();

 
命名空间(namespace)定义的是逻辑模块,而非实质模块。可以通过以下三种方式使用命名空间中的成员:

  1. /* 在头文件和源文件中都可使用。不会造成名字冲突,推荐使用。 */
  2. void fun1(const myns::string &str);

  3. /* 仅可以在源文件中使用。将myns命名空间中的string成员暴露出来。 */
  4. using myns::string;
  5. void fun2(const string &str);

  6. /* 仅可以在源文件中使用。将myns命名空间中的成员全部暴露出来,会面临名字冲突问题,应避免使用。*/
  7. using namespace myns;
  8. void fun3(const string &str);

 
阅读(575) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~