关于c++得一些搜集

来源:互联网 发布:js设置 类 样式 编辑:程序博客网 时间:2024/06/05 11:16

--vc中头文件声明应注意

#include   "stdafx.h"  
  应该检查是否在第一行显式的包含stdafx.h头文件,这是Microsoft   Visual   Studio为了加快编译   速度而设置的预编译头文件。在这个#include   "stdafx.h"行前面的所有代码将被忽略,所以其他头文件应该在这一行后面被包含 .  如果你有工程文件里的大多数.cpp文件需要.h文件,顺便将它们加在stdafx.h(后部) 

--typedef得用法

typedef用来声明一个别名,typedef后面的语法,是一个声明。
本来笔者以为这里不会产生什么误解的,但结果却出乎意料,产生误解的人不在少数。
罪魁祸首又是那些害人的教材。在这些教材中介绍typedef的时候通常会写出如下形式: typedef int PARA;
这种形式跟#define int PARA几乎一样,如前面几章所述,这些教材的宗旨是由浅入深,但实际做出来的行为却是以偏盖全。
的确,这种形式在所有形式中是最简单的,但却没有对 typedef进一步解释,使得不少人用#define的思维来看待typedef,
把int与PARA分开来看,int是一部分,PARA是另一部分,但实际上根本就不是这么一回事。int与PARA是一个整体!
就象int i:声明一样是一个整体声明,只不过int i定义了一个变量,而typedef定义了一个别名。
这些人由于持有这种错误的观念,就会无法理解如下一些声明: typedef int a[10]; typedef void (*p)(void);
他们会以为a[10]是int的别名,(*p)(void)是void的别名,但这样的别名看起来又似乎不是合法的名字,于是陷入困惑之中。
实际上,上面的语句把a声明为具有10个int元素的数组的类型别名,p是一种函数指针的类型别名。
虽然在功能上,typedef可以看作一个跟int PARA分离的动作,但语法上typedef属于存储类声明说明符,
因此严格来说,typedef int PARA整个是一个完整的声明。定义一个函数指针类型。
比如原函数是 void func(void); 那么定义的函数指针类型就是typedef void (*Fun)(void);
然后用此类型生成一个指向函数的指针: Fun func1; 当func1获取函数地址之后,
那么你就可以向调用原函数那样来使用这个函数指针: func1(void);

--const用法

引自http://www.cppblog.com/ivenher/articles/1643.html

const主要是为了程序的健壮型,减少程序出错.
最基本的用法,定义一个值不可改变得变量(有点自相矛盾得感觉^_^

参考http://baike.baidu.com/view/1065598.htm)
const int a=100;
int const b=100; //两者作用相同
const
指针和引用一般用在函数的参数中
int* m = &a; //
出错,常量只能用常指针
int c= 1;const int*pc = &c;//
常指针可指向常量 

const int* pa = &a; //
指针指向的内容为常量(就是b的值不变)
int const *a = &b; //
指针指向的内容为常量(就是b的值不变)*p=3//error
int* const a = &b; //
指针为常量,不能更改指针了如 a++但可以改值*p=3; 

从这可以看出const放在*左侧修饰的是指针的内容,const放在*右侧修饰的是指针
本身

const
引用的用法和指针一样
int const & a=b;
和指针一样
const int& a=b;
和指针一样
但没有 int& const a=b 的用法因为引用不能做移位运算,但只是出个warning 

const int* const a = &b; //
综合应用,一般用来传递多维的数组
类如:char* init[] = {"Paris","in the","Spring"};
void fun(const int* const a){}
fun(init)//
保护参数不被修改 

int A(int)const; //
是常函数,只能用在类中,调用它的对象不能改改变成员值
const int A(); //
返回的是常量,所以必须这么调用 cosnt int a=A();
int A(const int); //
参数不能改值,可用在任意函数
int A(const int*);
....
int height() const;//
常函数只能由常函数调用
int max(int,int) const;
int Max = max(height(),height()); 

const int* pHeap = new int;
delete pHeap;
p = NULL;//
出错
我的解决办法是强制类型转换
const int* pHeap = new int(1);
delete (int*)pHeap;
pHeap = NULL; 

一、const 和引用联合使用的时候要注意 

const int a = 1; 
const int& ref1 = a;
const int& ref2 = 1; 

ref1
ref2 都是正确的,但是他们引用的内容和一般的引用不同
const int& ref1 = a; 而言,其实这个 ref1 已经和 a 没有任何关系了
ref1
实际上是对一个临时量的引用。同理 const int& ref2 = 1; 也是对
一个临时量做的引用。当引用临时量是 C++ 的隐式类型转换可以起作用。
临时量的生存期和引用量的生存期相同。 

二、强传const对象可能导致无定义行为 

对于优化做的比较好的编译器,代码 const int i = 1;
当后面用到变量 i 的时候,编译器会优化掉对 i 的存取,而直接使用立即数

const int i = 1; 

*(const_cast<int*>(&i)) = 2;
cout << *(int*)&i << endl;
cout << i << endl; 

所以,对 const 对象做 const_cast 可能导致无定义行为
目前我就遇到这些问题,那位还有补充的吗 





能不能把自己的经验也谈谈。大家交流交流
这个就是我在调错时发现的
int height() const;//
常函数只能由常函数调用
int max(int,int) const;
int Max = max(height(),height()); 


Thinking again in C++
(一)常量性原理 cphj(原作) 
有些地方很受启发 


1.
不能将const修饰的对象赋值。
const int cx=100;
const int & rcx=cx;
const int * pcx=&cx;
cx=200; //error
rcx=200; //error
*pcx=200; //error 

2.const
类型的对象不能直接被non-const类型的别名所引用。
(1)
不能将const类型的对象传递给non-const类型的引用。
const int cx=100;
int & rx=cx; //error
(2)
不能将const类型的实参传递给形参为non-const类型引用的函数。
void f(int a)
{
}
void g(int & ra)
{
}
const int cx=100;
f(cx); //ok
g(cx); //error
(3)
不能将const类型的对象作为non-const类型引用的函数返回值。
int & f(const int & rca)
{
return rca; //error
}
int x=100;
f(x); 

3.
可以使用const类型别名引用non-const对象。此时通过const引用不能修改对象,但对象可以通过non-const引用被修改。
int x=100;
int & rx=x;
const int & rcx=x; //ok
x=200;
rx=200;
rcx=200; //error 

4.
指针的属性有两个:指针的类型和指针本身的常量性。其中,指向const对象与指向non-const对象,是不同的指针类型。
int x=100;
const int * pcx=&x; //[1]
int * px=&x; //[2]
int y=100;
int * const cpy=&y; //[3]
int * py=&y; //[4]
[1][2]
两个指针的类型不同;[3][4]两个指针的常量性不同。
对象与指向对象的指针的规则类似于对象与引用。即,const类型的对象不能直接被non-const类型的指针所指示(同2);可以使用const类型的指针指向non-const对象(同3)。 

5.
可以将相同类型(包括常量性)的const指针值赋给non-const指针。
int x=100;
int * px;
const int * pcx=&x;
px=pcx; //error
int * const cpx=&x;
px=cpx; //ok 

6.
若函数的返回值为内建类型或是指针,则该返回值自动成为const性质。但自定义类型则为non-const性质。
int f() //
相当于返回const int
{
return 100;
}
int * g(int & ra) //
相当于返回int * const
{
return &ra;
}
class CTest
{
int n;
public:
CTest(int n){this->n=n;}
};
CTest h() //
返回的就是CTest
{
return CTest(200);


f()=200; //error 

int x=100;
int y=200;
int * px=&x;
g(y)=px; //error
*g(y)=x; //ok
,从这点可以看出g()返回的不是const int * 

CTest t(100);
h()=t; //ok
,但却是完全错误的、危险的做法
//
所以h()的正确写法是返回const CTest


常函数的调用是这样的:常量对象只能调用常成员函数,非常量对象即可以调常成员函数,也可以调一般成员函数,但当某个函数有const和非const两个版本时,const对象调const版本,非const对象调非const版本
例:
class A
{
public:
int & GetData(){return data;}
const int & GetData()const {return data;}
private:
int data;

A a;
a.GetData();//
调用int & GetData(){return data;}
//
但如果没有这个函数,也可以调用const int & GetData()const 
const A const_a;
const_a.GetData();//
调用const int & GetData()const {return data;}
常函数只能调常函数,也是由于这个原因




原创粉丝点击