C++中需要注意的细节

1.switch的case语句中不能有定义部分,如果必须有定义部分,就要将它用{}包围起来

eg:(这部分中的case ‘s’如果不用{}包围就会报错)

char input;
		cin>>input;
		switch (input)
		{
		case 'q': cout<<"Processed terminated!"<<endl;break;
		case 's':
			{
				cout<<"Input destination folder:";
				string ofile_name;
				cin>>ofile_name;
				my_reader.write_file(ofile_name,true);break;
			}
		case 'f':
			cout<<"Word to query:";
			string query_word;
			cin>>query_word;
			my_reader.query(query_word);break;

		}

2.注意类对象的创建不可以使用 Class_name myobj()的形式,这相当于生命了一个函数,这个函数没有定义形参,返回值类型为Class_name.

3.可以使用单个实参来调用的构造函数定义了从形参类型到该类类型的一个隐式转换。

eg.

class Sales_item
	{
	public:
		Sales_item(const string& book=""):isbn(book){}
		Sales_item(istream& is);
		
		bool same_isbn(Sales_item& book){};
	};

	Sales_item item("1111-111-11-1");
	string null_book="9999-999-99-9";
	item.same_isbn(null_book);

观察上面小段代码的最后三行,当我们定义Sales_item对象item,并调用item的函数same_isbn,但是传递给它的是一个string类型的字符串,并不是该函数所期待的Sales_item对象,这时候编译器仍旧会顺利的接受这个调用,它通过调用接受一个参数的Sales_item类型的构造函数,生成一个新的临时对象,并将这个对象传递给same_isbn()函数。

        但我们不需要这种隐式转换的时候,只需要在类内部的构造函数声明之前加上explicit关键字就OK了,这个时候仍旧要使用null_book这个变量调用same_isbn函数就需要显式调用对应的构造函数了。就是将上述代码最后一行换成如下形式:

item.same_isbn(Sales_item(null_book));

4.友元声明只能出现在类定义的内部

5.类static成员函数不能声明为const类型,也不能声明为虚函数,并且在一个派生系列中一个static函数只会有一个实例

将一个函数声明为const意味着该函数对他所属对象的成员不作任何改变,这里的前提是这个函数要有他自己所属的对象,但是static函数不是任何对象的组成部分,所以不能将它定义为const。

6.static数据成员必须在类定义体的外部定义,并在定义时初始化。一个合适的场所就是将它的定义包含定义类普通成员的cpp文件中(这样正好满足static变量只能定义第一次的要求)。但是如果初始化式是一个常量表达式,const static成员变量就可以在类定义体内部进行初始化(这样初始化以后这个成员还是必须在类外部进行定义..居然是先初始化再定义...),即如下形式是合法的:

class Account
{
      ......
      static const int period = 30;
      static Account acc1;
      ......
}
static成员变量还有一个比较奇特的地方就是再类的内部可以声明一个该类类型的静态对象,而普通的成员最多只能声明指向该类的指针或者引用。上面一段代码中的第二行就是合法的。

7.用class和struct定义的类之间的差别有两点:

a.)默认的成员访问权限不同(class->private;struct ->public)

b.)默认的继承权限不一样(class->private;struct ->public)

8.友元的访问权限不可继承。如一个类要想同时对一个基类和派生类有特殊的访问权限就必须同时将他的友元资格分别写到基类和派生类的定义中;一个类内部成员要想同时能够被基类和对应的派生类访问就需要将派生类和基类同时作为友元声明到它自己的定义中。

9.当前作用域内声明的函数不会对上一级作用域中声明的函数进行重载,只会进行覆盖(变量也一样)。C++语言这一特性的更详细描述分为以下两种情况:

a)局部作用域中声明的函数不能构成对全局作用域中所声明函数的重载

b)派生类中定义的函数不会重载基类定义的函数(只会覆盖)

这一特性的形成原因是:编译器在编译这样一段程序的时候,只在当可能小的作用域范围内寻找匹配的函数名字,一旦找到就停止搜索,不会再到更高一层的作用域范围内进行寻找。

Eg.

class Base_class
{
public:
	int mem_func();
};

class Derived_class:public Base_class
{
public:
	int mem_func(int para);
};

int main()
{
	Base_class b;
	Derived_class d;
	b.mem_func();//ok calls the mem_func int the Base_class
	d.mem_func(10);//ok  calls the mem_func int the Derived_class
	d.Base_class::mem_func();//ok  calls the mem_func int the Base_class
	d.mem_func();//error Derived_class has no function named mem_func()!!!!!!!!!!!

	return 0;
}

10.输入输出操作符只能在类外部进行重载

在类内部重载的操作符第一个参数必须是指向当前对象的this指针,而输入输出操作符的第一个参数必须是输入或者输出流对象,所以只能在类外部对>>和<<进行重载,设定它的第一个参数是流对象,第二个参数是要输出的类对象的const引用。但是如果重载的操作符需要访问类对象的内部成员呢该怎么办呢?只要将该重载操作符的函数声明为该类的友元函数就OK了。



以下内容来自:http://write.blog.csdn.net/postlist 

1. C中static有什么作用?
(1)隐藏。 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,故使用static在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。
(2)static的第二个作用是保持变量内容的持久。存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量。
(3)static的第三个作用是默认初始化为0。其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是0×00,某些时候这一特点可以减少程序员的工作量。
2.C++中const有什么用?不要一听到const就说是常量,这样给考官一种在和一个外行交谈的感觉。应该说const修饰的内容不可改变就行了, 定义常量只是一种使用方式而已,还有const数据成员,const参数, const返回值, const成员函数等, 被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

3. C与C++各自是如何定义常量的?有什么不同?C中是使用宏#define定义, C++使用更好的const来定义。
区别:1)const是有数据类型的常量,而宏常量没有,编译器可以对前者进行静态类型安全检查,对后者仅是字符替换,没有类型安全检查,而且在字符替换时可能会产生意料不到的错误(边际效应)。2)有些编译器可以对const常量进行调试, 不能对宏调试。
4. 既然C++中有更好的const为什么还要使用宏?const无法代替宏作为卫哨来防止文件的重复包含。
5. C++中引用和指针的区别?引用是对象的别名, 操作引用就是操作这个对象, 必须在创建的同时有效得初始化(引用一个有效的对象, 不可为NULL), 初始化完毕就再也不可改变, 引用具有指针的效率, 又具有变量使用的方便性和直观性, 在语言层面上引用和对象的用法一样, 在二进制层面上引用一般都是通过指针来实现的, 只是编译器帮我们完成了转换. 之所以使用引用是为了用适当的工具做恰如其分的事, 体现了最小特权原则.
6. 说一说C与C++的内存分配方式?1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,如全局变量,static变量。2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。3)从堆上分配(动态内存分配)程序在运行的时候用malloc或new申请任意多少的内存,程序员负责在何时用free或delete释放内存。动态内存的生存期自己决定,使用非常灵活。
7. new/delete 与 malloc()/free() 的区别?malloc() 与 free() 是C语言的标准库函数, new/delete 是C++的运算符, 他们都可以用来申请和释放内存, malloc()和free()不在编译器控制权限之内, 不能把构造函数和析构函数的任务强加给他们.
8. #include<a.h>和#include“a.h” 有什么区别?答:对于#include <a.h> ,编译器从标准库路径开始搜索 a.h对于#include “a.h” ,编译器从用户的工作路径开始搜索 a.h
9. 在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”? C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为: void foo(int x, int y);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。
10. C++中的什么是多态性? 是如何实现的?多态性是面向对象程序设计语言继数据抽象和继承之后的第三个基本特征。它是在运行时出现的多态性通过派生类和虚函数实现。基类和派生类中使用同样的函数名, 完成不同的操作具体实现相隔离的另一类接口,即把“ w h a t”从“h o w”分离开来。多态性提高了代码的组织性和可读性,虚函数则根据类型的不同来进行不同的隔离。
11. 什么是动态特性?在绝大多数情况下, 程序的功能是在编译的时候就确定下来的, 我们称之为静态特性. 反之, 如果程序的功能是在运行时刻才能确定下来的, 则称之为动态特性。C++中, 虚函数,抽象基类, 动态绑定和多态构成了出色的动态特性。
12.什么是封装?C++中是如何实现的?封装来源于信息隐藏的设计理念, 是通过特性和行为的组合来创建新数据类型让接口与具体实现相隔离。C++中是通过类来实现的, 为了尽量避免某个模块的行为干扰同一系统中的其它模块,应该让模块仅仅公开必须让外界知道的接口.
13. 什么是RTTI?RTTI事指运行时类型识别(Run-time type identification)在只有一个指向基类的指针或引用时确定一个对象的准确类型。
14. 什么是拷贝构造函数?它是单个参数的构造函数,其参数是与它同属一类的对象的(常)引用;类定义中,如果未提供自己的拷贝构造函数,C++提供一个默认拷贝构造函数,该默认拷贝构造函数完成一个成员到一个成员的拷贝
15. 什么是深浅拷贝?浅拷贝是创建了一个对象用一个现成的对象初始化它的时候只是复制了成员(简单赋值)而没有拷贝分配给成员的资源(如给其指针变量成员分配了动态内存); 深拷贝是当一个对象创建时,如果分配了资源,就需要定义自己的拷贝构造函数,使之不但拷贝成员也拷贝分配给它的资源.
16.面向对象程序设计的优点?开发时间短, 效率高, 可靠性高。面向对象编程的编码具有高可重用性,可以在应用程序中大量采用成熟的类库(如STL),从而虽短了开发时间,软件易于维护和升级。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值