您的位置:首页 > 编程语言 > C语言/C++

c语言及c++若干注意事项(逐步添加)

2009-09-21 23:39 232 查看
一:宏定义不能换行,若要换行须用换行符\

运算符重载:

结论1:对二元运算符,将它重载为一个友元函数比重载为一个成员函数要便于使用。以支持交换率作为一个友元函数,二元运算符不要求第一个参数一定为某类的对象。

结论2:对一元运算符,将它重载为一个成员函数最恰当。重载为友员函数也可以。

妙招:给指针变量取别名

char a = 'M';

char *p = &a;

char * &pr = p;(取别名首先也是一个指针 故char * 然后才是引用符号,所以char * &pr = p;

以及由此推演 给指针的指针取别名 char ** &pr = p;

数组名和数组名取地址区别:

设int S[5] = {1,2,3,4,5};则S是数组的首地址(意思是数组首个元素的地址) ;&S是数组的地址。虽然值相同,但意义不同,从s+1和&s+1可知道其深层意义。

{
int num[5] = {1,2,3,4,5};
cout<<num<<endl;
cout<<num+1<<endl;
cout<<&num<<endl;
cout<<&num+1<<endl;
}


构造函数的特点如下

(1)构造函数是成员函数,函数体可写在类体内,也可写在类体外。

(2)构造函数是一个特殊的函数,该函数的名字与类名相同,该函数不指定类型说明,它有隐含的返回值,该值由系统内部使用。该函数可以有一个参数,也可以有多个参数。

(3)构造函数可以重载,即可以定义多个参数个数不同的函数。

(4)程序中不能直接调用构造函数,在创建对象时系统自动调用构造函数。

析构函数的特点如下

(1)析构函数是一个特殊的成员函数,它的名字同类名,并在前面加“~”字符,用来与构造函数加以区别。析构函数不指定数据类型,并且也没有参数。

(2)一个类中只能定义一个析构函数,析构函数不能重载。

(3)析构函数可以被调用,(如b.~Base();)也可以由系统调用。在下面两种情况下,析构函数会被自动调用。一是如果一个对象被定义在一个函数体内,则当这个函数结束时,该对象的析构函数被自动调用;二是当一个对象是使用new运算符被动创建的,在使用delete运算符释放它时,delete将会自动调用析构函数。

delete语句只能释放对象本身占用的内存(对象本身占用的内存用delete释放掉了,这个问题解决

如果这个对象在其生存期内打开了文间、数据连接或者使用了其他资源没有释放,析构函数就在对象本身被销毁前提供一个机会让程序员可以关闭文件、数据连接,释放其他资源。如果不释放这些资源就会出现随着程序运行,系统大量内存就被消耗掉的现象。

虚函数:

基类中的某个成员函数被声明为虚函数后,此虚函数就可以在一个或多个派生类中被重新定义.

在派生类中重新定义时,其函数原型,包括返回类型,函数名,参数个数,参数类型及参数的先后顺序,都必须与基类中的原型完全相同.

delete p 是一个两步的过程:调用析构函数,然后释放内存。

析构函数提供了一种和构造函数相反的机制,允许在销毁一个对象之前(亦即回收对象所占用的空间)让对象释放自己所使用的资源(这句话很精妙,也就是说,对象本身所占内存是怎么释放的在前边解决了,析构再解决对象使用过的资源---例如char *p = new char之类;这也解决了为什么普通构造函数没用new,则析构函数就不用delete的原因)

枚举类型使用问题:

C++ 中的枚举类型继承于 C 语言。就像其他从 C 语言继承过来的很多特性一样,C++ 枚举也有缺点,这其中最显著的莫过于作用域问题——在枚举类型中定义的常量,属于定义枚举的作用域,而不属于这个枚举类型。例如下面的示例:

enum FileAccess {

Read = 0x1,

Write = 0x2,

};

FileAccess access = ::Read; // 正确

FileAccess access = FileAccess::Read; // 错误

C++枚举的这个特点对于习惯面向对象和作用域概念的人来说是不可接受的。

函数指针数组

#include<stdio.h>

int fun(int a)

{

return a+1;

}

int main()

{

int (*p[10])(int);

int i;

p[0] = fun;

i = (p[0])(10);

printf("i=%d/n", i);

return 0;

}

p[10]为一个指针数组,而该指针数组里面的值为函数指针类型.让p[0]指向fun()函数.然后再进行调用,就可以调用到fun()这个函数了.

类的static函数访问非static成员

static Base::funA(Base* p)

{

p->m_num = ....;//大概这种形式

}

#undef 是在后面取消以前定义的宏定义(取消宏定义)

TRACE宏

TRACE宏对于VC下程序调试来说是很有用的东西,有着类似printf的功能;该宏仅仅在程序的DEBUG版本中出现,当RELEASE的时候该宏就完全消失了,从而帮助你调式也在RELEASE的时候减少代码量。

使用非常简单,格式如下:

TRACE("DDDDDDDDDDD");

  TRACE("wewe%d",333);

  同样还存在TRACE0,TRACE1,TRACE2。。。分别对应0,1,2。。个参数

COM接口

是一个C++基类,它定义了一组纯虚函数(只有纯虚函数),这些函数完全控制了其派生类行为的一些方面

1)接口是一组规则的集合,它规定了实现本接口的类或接口必须拥有的一组规则。体现了自然界“如果你是……则必须能……”的理念。

2)接口是在一定粒度视图上同类事物的抽象表示。注意这里我强调了在一定粒度视图上,因为“同类事物”这个概念是相对的,它因为粒度视图不同而不同。

面向接口编程: 在系统分析和架构中,分清层次和依赖关系,每个层次不是直接向其上层提供服务(即不是直接实例化在上层中),而是通过定义一组接口,仅向上层暴露其接口功能,上层对于下层仅仅是接口依赖,而不依赖具体类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: