侯捷C++面向对象高级开发
1、防卫式声明
用在头文件中
#ifndef __头文件的大写名字__
#define __头文件的大写名字__
代码块
#endif
防卫式声明的作用是:防止由于同一个头文件被包含多次,而导致了重复定义。 – “Car.h”,代码如下(并没有添加防卫式声明):
// Car.h
class Car
{
// ...
};
– “Person.h”,代码如下(包含了Car.h文件):
// Person.h
#include "Car.h"
class Person
{
public :
Car car;
};
– 在"main.cpp"中,我们同时include两个头文件:
// main.cpp
#include "Car.h"
#include "Person.h"
int main( int argc, const char * argv[]) <br>{
Person p;
}
此时,我们会发现编译出错:Redefinition of ‘Car’.
可是为什么会出现这样的情况呢?
我们需要知道,在预编译阶段,编译器会把.h文件展开,即main.cpp中的代码可以看做是:
class Car
{
// ...
};
class Car
{
// ...
};
class Person
{
public :
Car car;
};
int main( int argc, const char * argv[]) {
Person p;
}
此时class Car被包含两次,重复定义,出错。
2、内联函数,inline
内联函数效率更高
类内的函数本身就是inline函数,而类外的函数,我们可以在函数前面加上inline向编译器发出建议,让其变成inline函数。太过复杂的函数无法变成inline函数。 3、初始行和初始列,构造函数专业的写法,在构造函数参数后面使用
class A
{
public:
A(int a = 0, int b = 0)
:re(a),im(b)
{}
private:
int re, im;
}
来直接初始化类内数据,比在函数内赋值,可以提高效率。
默认实参,如果默认实参后面必须也是默认实参
complex(double r=0,double i) //错误,如果r和i互换位置,则正确
3、常量成员函数
如果成员函数不改变值,则应该用const进行修饰
double real () const {return re ;}
如果这里不加const
double real () {return re ;}
则
const complex c(2,1);
c.real(); //错误
因为这是一个常量类,但是类的成员函数不是const的,则调用会出错,相当于用一个非常量指针去操作常量指针的数据。
4、值传递和引用传递
一般都用引用传递,因为节省空间更有效率。
如果用引用,又不想更改值,则用常量引用
int b = 0;
const int & a = b;
5、友元函数
在类里声明友元函数,则非此类的成员函数,但属于友元函数,也能访问类里的private数据
6、 同一个类里的成员函数是友元函数、
都是complex类,c1的成员函数是c2的友元函数。 7、返回引用还是值
只有局部函数变量不能返回引用,因为其生存周期在函数执行完就结束了,其余的都可以返回引用。
|