C++启航

数据类型:struct、union、enum。
初始化: int x(1024)[直接初始化]

命名空间作用:区分相同的变量名。
定义命名空间:

namespace A{
    int x=0;
    bool b = true;
    void f1();
}

namespace B{
    int x=0;
    bool c=false;
    void f1();
}

cout << A::x << " " << B::c << endl;

引用:别名, int &b =a;

typedef AAA{
    int x=0;
}BBBB;
// BBBB 是AAA结构体的引用。

void swap(int &a, int &b){
    int c = a;
    a=b;
    b=c;
}

const: 常量

const int *p =NULL; /*===*/ int const *p = NULL; // *p不可改

int * const p = NULL;  // p 不可改

函数重载: 编译之后,采用函数名和参数类型形成一个新的函数名,调用的时候使用自动识别。

内联函数 inline:普通函数在编译时寻找函数的入口,然后执行函数。而内联函数则在编译是就用函数体覆盖了函数调用的语句。是不是内联由编译器决定。

内存的申请和释放:new 和 delete。

int *p = new int;
delete p;

int *p = new int[20];
delete []p;

// 实际应用: 判断内存是否申请成功!!!
int *p = new int[10];
if(p == NULL){
    // 内存申请失败
}

// 在释放内存后 需要把指针置空!!!
delete []p;
p = NULL;

对象的实例化:栈中实例化(函数的里的局部变量声明,就是在栈中申请内存)、堆中实例化(使用指针申请,是在堆中申请的内存)。

内存分区: [课程:封装篇上 6-1]

  1. 栈区:int x=0; int *p=NULL;
  2. 堆区:int *p=new int[20];
  3. 全局区:存储全局变量和静态变量
  4. 常量区:string str=”hello”;
  5. 代码区:存储逻辑代码的二进制

初始化列表:Student():age(10),name(“wy”) {},先于构造函数执行。

拷贝构造函数。

每个对象有自己的成员变量,但是会共享类里面的成员函数。使用this指针区分不同的对象。

const修饰成员函数,函数内不能修改成员变量的值。可以和非常成员函数同名,当对象是常对象时,调用const修饰的重载函数。反之则调用非const的成员函数。

继承: 覆盖 <——>隐藏

隐藏
B继承A,都有一个名为ABC()的函数,创建B类对象都用的ABC()函数,就是B类的ABC函数。如果想访问父类的函数:b.A::ABC()。

子类可以赋值给父类,父类不能赋值给子类。 父类=子类; 父类指针=子类对象

虚继承: class B: virtual public A,解决菱形继承问题。

静态多态(早绑定):就是在类里面的函数重载。
动态多态(晚绑定):继承,封装。B继承A,C继承A,ABC类里都有abc()函数,当使用A类的指针指向子类时,如果想调用子类的abc()函数,则需要在三个类里面的abc()函数前加virtual关键字。

虚析构函数:使用virtual修饰,当父类指针指向子类时,删除父类指针时不会调用子类的析构函数,使用virtual修饰则先调用子类的析构函数,然后调用父类的析构函数。解决内存泄漏问题。

virtual:不能修饰普通函数,只能修饰成员函数。不能修饰静态函数,不能修饰内联函数。不能修饰构造函数。

函数指针,

多态的原理:
如果类里面有虚函数,在存数据成员的同时会有一个 虚函数表指针 ,指向一个虚函数表,虚函数表里存的是虚函数的入口地址。指针的位置在对象的第一个内存地址。

如果子类没有定义和父类同名虚函数,则子类的指针执行的是父类函数,如果定义了同名虚函数 ,则指向了子类的函数入口地址,这就是覆盖。

纯虚函数: virtual void func()=0; 纯虚函数在虚函数表的值是0

含有纯虚函数的类叫抽象类。抽象类无法实例对象。

仅含有纯虚函数的类就是接口类。

RTTI : 运行时类型识别。

判断是否是相同的类型:typeid (*p) == typeid(CLASSNAME)

dynamic_case注意事项:
只能用于指针和引用的转换。要转换的类型必须含有虚函数。转换成功返回子类型的地址,失败返回NULL。
typeid注意事项:
type_id返回一个type_info对象引用。如果想通过基类的指针获得派生类的数据类型,基类必须带有虚函数。只能获取对象的实际类型。
try{
    // do some thing and throw ...
}
catch(Exception &e){
    // e->print();
}
catch (...){
    // all kinds of exception
}

友元函数: friend void function(Class &A); 函数的参数必须是类型的引用或者是类的指针,能通过它访问类的私有和保护的数据成员。

友元成员函数:

class B{
    // friend void func(B &b);
    friend void A::func(B &b);
public:
    B();
private:
    int x;
    int y;
}

友元类:

class A;
class B{
    friend A;
public:
    B();
private:
    int x;
    int y;
}

A可以建立B的对象, 并可以访问B的私有数据成员和函数。
友元不能传递,友元关系是单向的。

静态数据成员,在类的外部初始化,不能在构造函数中初始化。
静态的函数只能调用静态的函数和数据成员,非静态都能调用。

运算符的重载:友元函数的重载,成员函数的重载。

class A{
// friend A& operator-(A &a);
public:
    A& operator -();

    A& operator ++(); // 前置重载
    A operator ++(int); // 后置重载,参数是为了标识是后置重载

    A operator +(const A &a){
        // do add operator
        return temp;
    }
}
A& A::operator -(){
    // do something;
    return *this;
}


// typename 和class 作用一样
template<class T>  // template <typename T, typename C>
T max(T a, T b){
    return (a>b)?a:b;
}

template<typename T, int size>
void dis(T t){
    cout << size <<endl;
    cout << t<<endl;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值