c++知识点
- Static关键字
1.1 C语言中的static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0
1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
3). 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
1.2 C++中
1)静态类数据成员
无论建立多少个类的对象,都只有一个静态数据的拷贝。静态数据的初始化是在类外进行的。
2)静态类函数
它属于整个类,一般在静态成员函数中访问的基本上是静态数据成员或全局变量。
2. 友元
2.1 友元函数
在类中说明的某个函数不是该类的成员函数,可以访问该类的私有函数
#include <string.h>
#include <iostream.h>
Class test {
int x; //private
public:
test(int vx) {x=vx;}
friend int get_x(test t1); //friend函数
}
main()
{
test t1(10);
cout<<”x is:”<<get_x(t1)<<”\n”;
}
2.2 友元成员
另一个类的成员函数也可以作为某个类的友元,可以两个类合作完成一个任务。
Class A;
Class B;
{
…
public:
void set_a(A* a);
friend void A::set_b(B* b);
}
class A
{
…
public:
void set_b(B* b);
friend void B::set_a(A* a);
}
2.3 友元类
A类是B类的友元,意味着A类可以访问B类的所有私有成员。
- 重载
同样函数名使用不同类型的参数或参数个数不同
3.1 运算符重载 type operator @ (参数表)
例如:
Class x{
int operator + (x a);
}
3.2 ++/--重载,带参数的是后置
前置++运算符的重载方式:
成员函数的重载: 函数类型& operator++()
友元函数的重载:friend 函数类型& operator++(类类型& )
后置++运算符的重载方式:
成员函数的重载:函数类型& operator++(int)
友元函数的重载:friend 函数类型& operator++(类类型&, int)
3.3 运算符()和[]只能是成员函数重载不能用于友元重载
3.4 赋值=重载只能是成员函数,不能被继承
void operator = (class *)
3.5 不是所有运算符可以重载,如“.”、“::”、“?:”和“sizeof”
- 引用与指针
4.1 区别
1)引用不可以为空,但指针可以为空
2)引用不可以改变指向,对一个对象"至死不渝";但是指针可以改变指向,而指向其它对象
3)引用的大小是所指向的变量的大小,因为引用只是一个别名而已;指针是指针本身的大小,4个字节
4) 重载运算符不能对指针单独操作
5) 指针和引用的自增(++)运算不同,指针是地址偏移,引用是数值自增
4.2特别之处const
1)常量指针VS常量引用
常量指针:指向常量的指针,在指针定义语句的类型前加const,表示指向的对象是常量。
int i=10;const int* p=&i;
常量引用:指向常量的引用,在引用定义语句的类型前加const,表示指向的对象是常量。
也跟指针一样不能利用引用对指向的变量进行重新赋值操作。
int i=10; const int& ref=i;
2) 常量指针常量VS常量引用常量
常量指针常量:指向常量的指针常量,可以定义一个指向常量的指针常量,它必须在定义时初始化。常量指针常量定义"const int* const pointer=&c"告诉编译器,pointer和*pointer都是常量,他们都不能作为左值进行操作。
而就不存在所谓的"常量引用常量",因为跟上面讲的一样引用变量就是引用常量。C++不区分变量的const引用和const变量的引用。程序决不能给引用本身重新赋值,使他指向另一个变量,因此引用总是const的。如果对引用应用关键字const,起作用就是使其目标称为const变量。即没有:Const double const& a=1;只有const double& a=1;
- 菱形继承
5.1 虚基类继承
当多条继承路径上有公共基类,若想保存这个公共基类的一个实例,可以定义为虚基类
构造顺序:
1) 虚基类在非虚之前调用
2) 同一层次,按说明顺序调用
3) 虚基类由非虚基类派生,仍然先基类后派生类
5.2 父类实现,子类没有虚拟继承,显示的调用
class CBase
{
public:
virtual void test()
{
cout << "CBase::test()" << endl;
}
};
class CDerived1 : public CBase {};
class CDerived2 : public CBase {};
class CTest : public CDerived1, public CDerived2 {};
void main()
{
CTest test;
test.CDerived1::test(); //explicitly specify super class
}
5.3 用组合而不是继承,代替菱形继承
6. 虚函数
#include "stdafx.h"
#include <string.h>
#include <iostream>
using namespace std;
class base {
public:
virtual void foo(int i = 50) { cout << "base " << i; }
};
class derived : public base {
public:
virtual void foo(int i = 20) { cout << "derived "<< i; }
};
int _tmain(int argc, _TCHAR* argv[])
{
derived d;
base& b = d;
b.foo();
return 0;
}
输出:derived 50