Cpp

函数

cpp对函数之间的的排列要满足先定义后使用。后定义先调用的函数必须声明。因为在函数被调用之前,应当让编译器知道该函数的原型。

内存区域

  • 代码区
    • 存放程序的可执行代码
  • 全局数据区
    • 静态变量
    • 一般的全局变量(自动初始化为0)
  • 栈区
    • 局部变量(不处理原内存中的值)
  • 堆区
    • 与指针有关的动态数据

变量

全局变量若和局部变量同名,需要加上::

static

static修饰的变量为静态变量、内部变量。其中局部静态变量具有局部作用域,但是却具有全局生存期。

static变量作为类的静态变量时,需要在类外部(.cpp)进行定义,如

float Stub::staticVariable=0;

静态函数成员的调用

Stub::stubmethod();

extern作用域从定义处到当前文件结束

默认参数

1
void showArea(int a = 0,int b = 10)

模板

函数模板
1
2
3
4
template <class T>
void swap(T &left , T &right){
//todo
}
类模板

编译器看到类模板时并不为它分配内存空间,直到定义了一个模板对象,即模板参数由编译器替换时,才为其分配空间。

1
2
3
4
5
6
template < class T >
class Stub{

}

Stub<int> initStub;

内联函数

一定要放在头文件中

方法是加上inline关键字

编译器在编译时,会将内联函数采用函数体进行替换,是以增加目标代码为代价来换取时间的。

指针

1
2
3
4
5
6
7
8
9
10
11
//返回指针 
float *search(float (*p)[4],int n){
return *(p+n);
 }

//一种错误情况,局部变量导致系统释放空间,使得返回的地址无效
char *getName(){
char name[81];

return name;
}

void指针表示任何类型。但是不能对其使用算数操作。

const可以修饰类型、变量名

  • 修饰类型表示不可以通过指针改变现在所指的内容
  • 修饰变量名,表示可以改变指针所指向空间的内容

Main

1
2
3
int main(int argc , char *argv[]){

}

内存的动态分配和释放

new和delete

1
2
3
4
5
6
7
8
9
10
11
12
13
int *iptr = new int;
int *iptr = new int(30);

int *a;
a = new int[100];
//若空间不足 new int会返回0或NULL
if(NULL == a){
exit(0);
}

//释放
delete a;
delete [] a;

malloc和free

1
2
3
4
NODE * NODE;
NODE = (NODE*) malloc(sizeof(NODE));

free(NODE);

结构体

1
typedef char NAME[100];

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Stub{
private:
int a;
public:
void calculate();
}

//类外部定义函数需要用两个引号
void stub::calculate(){
return;
}

//新建类
 Stub stub;

.h文件和.cpp文件

将类的定义存储在头文件中,函数成员放在cpp文件中

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
//Rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle{
public:
void setData(float,float);
void calculate();
private:
float width;
float height;
}

//Rectangle.cpp
#include <iostream>
using namespace std;
#include "Rectangle.h"

void Rectangle::setData(float w,float l){
width = w;
height = l;
}

void Rectangle::calculate(){

}

友元函数

友元函数不是类中的函数成员,但它可以访问类中定义的私有成员。

友元破坏了数据的封装和隐藏,尽量不使用或少适用友元。

外部函数作为类的友元

1
2
3
4
5
6
7
//类中定义
friend double Distance(Point &a,Point &b);

//外部函数定义
double Distance(Point &a , Point &b){

}

类的成员函数作为另一个类的友元

这样的成员函数也被称为友元成员。既可以访问所在类对象的私有成员,也可以访问friend声明语句所在类对象中的私有成员和公有成员。

1
2
3
4
5
6
7
8
9
10
11
class Budget{
private:
float divBudget;
public:
friend void Aux::addBudget(float , Budget &);
}

//Aux.cpp
void Aux::addBudget(float , Budget &){
divBudget++;
}

一个类作为另外一个类的友元

B类中的每个函数成员都能访问A类中的私有成员。

1
2
3
4
5
class A{
public:
void Display();
friend class B;
}

拷贝构造函数

并不调用构造函数,而是采用对象按位拷贝操作,将b对象的每个成员复制到a中。这样如果b中有指针,a中也会有指针,而a对象在析构的时候可能会删除指针指向的内容,导致b对象错乱。

1
Stub a = b;

拷贝构造函数是特殊的构造函数,当采用一个对象初始化另一个对象时,将自动调用该函数。

拷贝构造函数在对象被创建时调用,而赋值函数在对象已经存在的情况下调用。

1
2
3
4
5
6
7
8
9
10
11
class Stub{
public:
Stub(const Stub &obj){
name = new char[strlen(obj.name)+1];
strcpy(name,obj.name);
age = obj.age;
}
private:
char *name;
int age;
}

操作符重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Stub{
public:
void operator =(const Stub &right){

}

Stub operator ++();//prefix
Stub operator ++(int);//post
ostream &operator <<(ostream &strm , Stub &stub){
strm <<stub.XXX;
return strm;
}

//类型转换
operator float(){
return 12.0;
}
}

技巧

创建一个临时对象将其返回 和 创建一个局部变量并返回 是不同的。

场景1:

  1. 创建一个temp对象,调用构造函数完成初始化;
  2. 拷贝构造函数将temp赋值到内存的外部存储中;
  3. 在函数结束时,摧毁temp对象

而场景2:直接把临时对象创建并初始化在内存的外部存储单元中,省去了调用拷贝构造函数和析构函数的过程,提高了效率。

1
2
3
4
5
6
7
8
// 1
string temp(s1+s2);
return temp;

// 2
return string(s1+s2);

12

继承

CPP可以多重继承,其中子类的同名函数需要作用域分隔符::来确定要调用的函数

1
2
3
4
5
6
7
8
class Son : public Father {

}

//构造函数
Son::Son(string name):Father(name)

//public、protected、private为继承修饰符,控制可见性。

异常

1
2
3
4
5
6
7
8
9
10
11
12
13
float divide(int dividend , int divisor){
if(divisor == 0 ){
throw "error";
}else{
return float (dividend)/divisor;
}
}

try{
divide(a,b);
}catch(char* exceptionString){
cout << exceptionString;
}

初始化列表

构造函数参数表和函数体之间,在构造函数的函数体执行之前完成初始化列表中指定的工作。

  1. 具有继承关系的子类必须在初始化列表中调用基类的构造函数
  2. 类中的const常量成员只能在初始化列表中进行初始化
  3. 对象类型的成员的初始化放在初始化列表中则程序的效率较高

Virtual

CPP编译器在默认情况下,对函数成员的调用实施的是静态绑定。如需改为动态绑定,需要增加前缀virtual

虚函数是一个函数成员,唯一要求是在子类中一定要覆盖它。

纯虚函数

virtual <> <>() = 0;

其他

CPP中字符串末尾要有\0

0%