03 函数
-
一、 使用具有默认参数的函数
- 不可以靠左边缺省
- 只能给出一次缺省值
- 声明时给出了缺省值,定义时不能重复给出
-
二、 内联函数
- 实质是用目标程序的长度来换取执行时间。程序代码占用多份空间,但免去调用的额外开销。
- 一般把规模很小但频繁调用的函数声明成内联
- 使用inline,只是请求编译器内联该函数,是否内联由编译器决定。
-
三、 变量的作用域
- 在C++中,变量作用域可以分为三类(C语言中,作用域包括前两类):
- 块作用域(函数作用域):局部变量
- 文件作用域:全局变量
- 类的作用域:全局变量,C++专属,本章不涉及
- 全局变量与局部变量同名时,局部变量优先。可以利用域作用符::区分两者
- 在C++中,变量作用域可以分为三类(C语言中,作用域包括前两类):
-
四、 变量的生命周期
- 储存类别
- 1.程序代码区—存放函数体的二进制代码(忽略)
- 2.静态区(static):一旦分配,直到程序结束才回收(终 生不死);全局变量,静态局部变量
- 3.栈(Stack):存储函数参数和局部变量,空间由系统自动动态分配,回收。函数被调用,分配,压栈;执行完, 回收,弹出。特点:空间小(xMB量级),速度快
- 4.堆(Heap):程序员动态申请的内存块,new申请, delete释放(Java自动释放)。特点:空间大(xGB量 级),速度慢。对于C/C++,如果程序员忘记回收,终 生不死,直到操作系统关闭。
- 变量--->储存类别
- 全局变量--->静态区
- 静态局部变量--->静态区
- 缺省局部变量-->动态区
- 寄存器变量--->在cpu内部储存
- 储存类别
-
五、 全局变量的存储方式(extern,static)
- 用static声明静态变量
- static局部变量:存储在静态存储区,在函数内部定义,只限在函数内部使用
- static全局变量:存储在静态存储区,在函数外部定义,只限在本文件中使用
- extern全局变量:存储在静态存储区,在其他文件中定义,在本文件中可以使用
- 用static声明静态变量
-
六、 内部函数外部函数
- 内部函数:函数只局限于在本文件中调用,其它文件不能调用,用static定义该函数。
- 外部函数:函数的默认形式。
- 在调用文件中用extern 声明,把该函数的作用域扩展到调用文件。
06 类和对象的使用
- 一、 构造函数
class A {
float x, y, z;
public:
A(float a, float b = 10) {
x = a;
y = b;
z = 0;
}
A(float a, float b, float c) : x(a), y(b), z(c) {
}
A() = default;
};
- 二、 析构函数
在对象的生命期结束时,系统自动调用析构函数,收回为对象分配的存储空间。 作用与构造函数正好相反。
~A() {
cout << "这个对象被析构了";
}
- 三、 复制构造函数
class Str {
int length;
char *sp;
public:
Str(char *str) {
if (str) {
length = strlen(str);
sp = new char[length + 1];
strcpy(sp, str);
} else sp = 0;
}
void show() { cout << sp << endl; }
Str(const Str &s);
~Str() {
if (sp) delete[]sp;
}
};
//浅拷贝
//Str::Str(const Str &s) {//隐含的复制构造函数
// length = s.length;
// sp = s.sp;
//}
//深拷贝
Str::Str(const Str &s) {
if (s.sp) {
length = s.length;
sp = new char[s.length + 1];
strcpy(sp, s.sp);
} else {
sp = 0;
}
}
- 四、 赋值运算符(重载)函数
#include <iostream>
using namespace std;
class Stu {
int age;
public:
Stu() {}
Stu(int age) : age(age) {}
int operator+(const Stu &s) {
return age + s.age;
}
friend ostream &operator<<(ostream &output, Stu &s) {
output << "年龄: " << s.age;
return output;
}
friend istream &operator>>(istream &input, Stu &s) {
input >> s.age;
return input;
}
};
int main() {
Stu s1(14), s2;
cin >> s2;
cout << s1 + s2 << endl;
cout << s2;
}
08 继承和派生
继承的概念-派生类的构造函数和析构函数
- 派生类构造函数
- 首先调用基类的构造函数来初始化基类成员和子对象
- 然后对其中包含的对象以及成员变量初始化
- 最后调用自身构造函数
- 派生类构造函数名(总参数表列): 基类构造函数名(参数表列) ,子对象名(参数表列) { 派生类中新增数据成员初始化语句 }
- 在派生类对象释放时,顺序相反。
class A {
int name;
public:
A(int n) : name(n) {
cout << "A_" << name << "构造了"<<endl;
}
~A() {
cout << "A_" << name << "析构了"<<endl;
}
};
class B : public A {
int age;
int n;
A a;
public:
B(int g, int n) : age(g), a(22), A(n) {
cout << "B_" << age << "构造了"<<endl;
}
~B() {
cout << "B_" << age << "析构了"<<endl;
}
};
int main() {
B b(1, 1);
}
A_1构造了
A_22构造了
B_1构造了
B_1析构了
A_22析构了
A_1析构了
多重继承
-
调用基类构造函数的顺序:按照声明派生类时基类出现的顺序
-
二义性,需使用virtual
class A {
public:
int x;
A(int a = 0) { x = a; }
};
class B : virtual public A {
public:
B(int a) : A(a) {}
};
class C : virtual public A {
public:
C(int a) : A(a) {}
};
class D : public B, public C {
public:
D(int a, int b, int c) : B(b), C(c), A(a) {}
};
int main() {
D d(1, 2, 3);
cout << d.x << endl;
}
多态
- 编译时的多态性,静态多态(函数重载、运算符重载)
- 运行时的多态性,动态多态(虚函数)
class A {
public:
virtual void print() { cout << "A" << "\t"; }
};
class B : public A {
public:
void print() { cout << "B" << "\t"; }
};
class C : public A {
public:
void print() { cout << "C" << "\n"; }
};
int main() {
A a, *pa;
B b; C c;
a.print();
b.print();
c.print();
pa = &a; pa->print();
pa = &b; pa->print();
pa = &c; pa->print();
}
Comments | 0 条评论