函数内联
- 函数内联,其目的是为了提高函数的执行效率。
- 关键字Inline必须与函数体放在一起才能够使函数成为内联,仅将inline放在函数声明前面不起任何作用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25//错误
inline void Foo(int a,int b);
//正确
void Foo(int a,int b);
inline void Foo(int a,int b)
{
}
//内联,不提倡
class A
{
public :
void Foo(int a)
{
}
};
//内联,提倡
class A
{
public :
void Foo(int a);
}
inline void A::Foo(int a)
{
}慎用内联,内联是以代码膨胀为代价的,仅仅省去了函数调用的开销
- 内联的工作方式。对于任何内联函数,编译器在符号表中放入函数的名称、返回值、参数等。如果内联函数没有错误,整个函数体也会被放到符号表中。在进行内联函数的调用时,编译器首先会检查调用是否安全,如果安全的话,内联函数的代码就会直接替换为函数调用,从而省去了函数调用的开销。
- 不宜使用内联的情况
- 函数体内的代码过长。
- 函数体内出现循环
编程是多费了一些心思,少了一些痛快,这才是编程的艺术。
构造、析构、拷贝、赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using namespace std;
class String
{
public:
String(char *str=NULL);
String(const String &other);
String& operator =(const String &other);
~String(void);
private:
char *m_Data;
};
String::String(char *str)
{
if(str==NULL)
{
m_Data=new char[1] ;
*m_Data='\0';
}
else
{
m_Data=new char[strlen(str)+1];
strcpy(m_Data,str);
}
}
String::String(const String &other)
{
m_Data=new char[strlen(other.m_Data)+1];
strcpy(m_Data,other.m_Data);
}
String& String::operator =(const String &other)
{
if(this==&other)
return *this;
delete [] m_Data;
m_Data=new char[strlen(other.m_Data)+1];
strcpy(m_Data,other.m_Data);
return *this;
}
String::~String()
{
delete [] m_Data;
}
int main()
{
return 0;
}
对于任意一个类,C++编译器会自动为类产生四个缺省的函数:构造函数、析构函数、拷贝函数、赋值函数。
一只公鸡使劲地追赶一只刚刚下蛋的母鸡,因为母鸡下了鸭蛋。
.h .gch文件
- 概念
- gch即预编译头,将头文件预编译为二进制代码后后续编译使用。当多个源文件包含一个头文件,正常流程是将其在每个源文件中解析一遍,造成重复浪费。使用gch,将头文件作预编译头形成中间处理的二进制代码,然后再包含进源文件中。
- 适用
- gch适用于被多个源文件包含的头文件,且头文件不会经常做修改。
- 注意
- .h文件叫做头文件,不能够被编译。”#include”叫做编译预处理指令,可以简单理解成,在1.cpp中的”#include 1.h”指令把1.h中的代码在编译前添加在了1.cpp的头部。
- 每个.cpp文件都会被编译,生成一个.obj文件,然后所有的.obj文件链接所有的.obj文件链接起来,可执行文件就生成了。
- c语言和c++都是这样的,声明和定义要分开。要想使用的话需要使用extern
pragma once 与 ifndef
- pragma once 是新兴的防止头文件被重复包含的语句。两者区别见pragma once 与 ifndef的区别
- if 与 else 匹配问题
与是完全不同的两个运行结果。原因是作用域的问题。 为什么使用using namespace std;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
C++中为了避免名字定义冲突,特别引入了“名字空间的定义”,即namespace。
当代码中用<iostream.h>时,输出可直接引用cout<<x;//<iostream.h>继承C语言的标准库文件,未引入名字空间定义,所以可直接使用。
当代码中引入<iostream>时,输出需要引用std::cout<<x;如果还是按原来的方法就会有错。
使用<iostream>时,引入std::有以下方法:
1.
using namespace std;
cout<<x;
2.
using std::cout;
cout<<x;
3.
最基本的std::cout<<x;
这回你该知道为什么通常用
要用using namespace std;了吧。如果你不用这个,就要在使用cout时,用后两种方法了。
其他头文件也是同样的道理。
(有“.h”的就是非标准的,C的标准库函数,无“.h”的,就要用到命令空间,是C++的。还有一部分不完全是有“.h”和没“.h”的差别。例如:math.h和cmath)为什么在c++程序里可以直接用printf 和scanf
- iostream是没有包含C语言中的输入输出函数的,这个头文件是C++中输入输出流的,你那种情况一般是编译环境默认连接了stdio.h造成的。那是不是要用c的输入输出加上<stdio.h>比较安全?是不是所有编译器都支持这种连接呢?应该是的,头文件的默认添加可以在编译环境中设置。不过原则上是应该加上相应的头文件的,一般还加上头文件比较好。