C-C++补充

变量可用表达式初始化

{}内部作用域,可定义与外部变量同名的变量。内部变量隐藏了外部变量(新定义的变量说了算)

在for循环中可以定义局部变量,作用于for循环这一内部作用域

在函数内部,想要访问和内部变量同名的全局变量,可使用全局作用域限定"::"

        eg:cout<<::a<<endl;        //输出全局变量a

引用,不涉及将实参拷贝给形参(传值),无额外内存开销,效率高,尤其当实参占据很大内存时

想提高效率,又不希望形参的修改影响实参,可以将形参类型写为const int& x,就无法在子函数中对其进行修改了

inline(在函数最前方加上该关键字)内联函数,为了解决频繁调用小函数,占用大量栈空间的问题。将函数调用,替换成函数中的简单语句,以提高程序执行效率。

小函数中不能包含复杂的结构控制语句,且不能递归(程序调用自身),编译器才会将内联函数,内联展开

try-catch处理异常情况,正常代码放在try块,catch中捕获try块抛出的异常

throw,抛出异常对象,在try块中throw后,try块中其余的代码就都不会执行了

catch(...){...},万能接盘侠,接收之前没被捕获到的异常

                try{

                        if(num>50) throw 1;

                        if(num<50) throw 1;

                       throw "hello";

                }

                catch(int result){  //这个catch块只能捕获到整形异常。字符串类异常可用const char* s来捕获

                        ...

                }

重载,分为函数重载(类型或个数不同)、运算符重载。允许在同一作用域中,为函数和运算符指定多个定义。

运算符重载,当用户自定义类型使用运算符时,需进行运算符重载。

        编译器转换成的函数形式:operator<<(cout,m);        //其中m为Man类型

声明模板类型参数时,typename全面优于class

当T是一个类,且这个类有子类时,应该用template <typename T>。

typename T::innerClass myInnerObject,此时不能用class。typename告诉编译器,T::innerClass是一个类innerClass是T的子类,程序要声明一个T::innerClass类的对象,而不是声明T的静态成员innerClass。

        template<typename T1,typename T2>

        T1 findMin(T1 a, T2 b) {    //T1整形,T2浮点型

                if (a<b)

                {

                        return a;

                }

                return /*(T1)*/b;

        }

C语言中,void* calloc(int a,int b);void* malloc(int a);void* realloc(void* a,int b)

malloc,开辟a个字节;不进行初始化;需要强转

calloc,开辟a*b个字节;初始化成ASCII值为0(NULL);需要强转

realloc,①若指针a所指空间的后面,有足够的空间增加至总共b个字节,则直接扩充;②若空间不够,则开辟新空间+复制过去+释放旧空间+返回指向新空间的指针;需要强转。参数a必须是动态开辟的地址,不能是静态定义的数组的地址。

        强制类型转换,限定了步长

C++中,new与delete,对类对象调用了构造函数与析构函数

可以直接new一个动态数组,eg:n=8;    double* p=new double[n];

#define _CRT_SECURE_NO_WARNINGS,Windows系统下使用

类(class),在C语言struct基础上,增加了成员函数,现两者皆可

成员函数的自引用,"return *this;(返回自身的引用)"使该成员函数可以串起来连续使用,eg:d.add(2).add(3)

        Date& add(int i){

                day=day+i;   //increment,n.增量[数]

                return *this;   //this是指向调用这个函数的(类的)对象的指针   //*this是调用这个函数的那个对象

        }

在类中成员函数的重载

        重载运算符+=时,应注意运算符优先级中的结合方向,为从右向左,故(d += 3) += 5;,否则从右向左时,3是常量(err:表达式必须是可修改的左值)

在构造函数的形参中,给所有成员变量赋初值,就可以在少参和无参时定义变量了

eg:Date day、Date day(2021)、Date day(2021,9)、Date day(2021,9,26)皆可

可以在构造函数中,分配内存、打开文件、打开网络端口等

可以在析构函数中,将内存还给操作系统,关闭文件,关闭网络端口等

间接访问private成员,写一个get_...的函数。

        public:

                char* get_name() {return name;}        //写函数

        stu.get_name()        //间接访问

同理,间接修改private成员,写一个set_...的函数。释放原来空间,再开辟,拷贝。

        void set_name(char* n="new_name")   //修改不需要返回值   //可以提供默认参数,以应对不提供参数的情况

"public:"部分,称为这个类对外界公开的接口

拷贝,分为①拷贝构造函数(定义一个类对象时,用同类型的另外对象对其进行初始化),和②赋值运算符(一个对象赋值给另一个对象)。

        即student s(m);,和m=n;

虽然编译器会自动生成这两个东西,但因为Student类中的成员变量涉及到内存分配,所以使用默认的拷贝构造函数会出错,故需要重载相应的拷贝构造函数与赋值运算符。

在类外定义成员函数,在类内声明+在类外加上类的作用域(eg:void Date::print() {...}),说明print()不是全局函数,而是该类的成员函数。

用模板类时,要写上类模板的<参数列表>。即在内部有template类型变量的类后加上尖括号,并在里面写上变量类型,eg:Array<double> arr;

cerr,eg:cerr<<endl<<...<<endl;

typedef用途,typedef int(或long) INT,可以使不同操作系统下INT的字节数相同

string的API:

        (1)string("...",6);,取字符串"..."中的前6个字符构成新字符串

        (2)string("...",4,6);,从字符串"..."下标为4的字符开始,往后取6个字符构成新字符串

        (3)string(6,'*');,一个由6个*号构成的字符串

        (4)string(s4.begin(),s4.end()-3);,s4.begin()指向开头字符,s4.end()指向结尾字符'\0',两者都是指针,截取两者之间的那段字符串。string(start iterator迭代器,end iterator)

                s.size(),字符串s的字符个数

        (5)...+...,将2个字符串相连

用字符串迭代器遍历字符串:,迭代器变量是一个指针
        string s = "helloworld!";

        //string::const_iterator ci;    //常量迭代器,不可以修改字符(不能给常量赋值)

        string::iterator ci;    //普通迭代器,可以修改字符

        int i = 0;

        for (ci = s.begin(); ci != s.end(); ci++){

                *ci = 'a';

                cout << i << " " << *ci << endl;

                i++;

        }

size_type和size_t:

size_type,机器不同长度不同,使得程序与机器相匹配,size_type是string类和vector类定义的类,用于保存string对象和vector对象的长度,标准库类将size_type定义为unsigned类型;

size_t,增强程序在不同平台上的可移植性,C/C++标准只定义了变量类型的相对关系,没有固定各类型的具体大小,各系统在内存中又分为高位对齐存储和低位对齐存储。

常函数和常对象:

常函数(函数被调用,函数内部的操作),①常函数能被普通对象或常对象调用,②常函数不能“写”普通成员变量,除非有mutable(a.可变的)关键词修饰

常对象(调用函数,对象的操作),①常对象只能调用常函数,不能调用普通函数②常对象只能读成员变量

inheritance继承(derivation派生),一个derived class派生类,从一个或多个parent class父类/base class基类继承,继承父类的属性和行为,但其也有自己的特有属性和行为

        eg:class Manager : public Employee{...};        //public,private,protected

初始化成员列表,Employee::Employee(string n) :name(n) {},Manager::Manager(string n, int l) :Employee(n), level(l) {}

通过调用基类的print函数,以实现输出派生类成员变量+父类(基类)成员变量

        void Manager::print() {
            cout << "L" << level << " ";        //既输出了经理的级别
            Employee::print();        //又输出了雇员的名字
        }

基类指针可以指向派生类对象,反之派生类指针无法指向基类对象。故可以用一个指向基类的指针,分别指向基类对象和派生类对象

多态,基类函数前加virtual,基类指针会根据实际指向的对象类型,调用相应的函数。

只有当一个类作为基类的时候,才会把函数变成虚函数,以实现多态。

virtual关键字加在析构函数之前,声明成虚函数。虚析构函数,使得派生类申请的空间也会得到释放,防止内存泄露。

多重继承(派生derivation)Multiple inheritance,多个类派生出一个类

当然,一个类可以派生出多个类

纯虚函数pure virtual function,函数体=0的虚函数,eg:virtual const char* speak()=0;

抽象类abstract base class,包含纯虚函数的类,抽象类不能实例化(不能创建对象)。从抽象类派生的类如果没有继承实现所有的纯虚函数,则仍然是抽象类。反之若将纯虚函数都实现了,就不是抽象类了,就能创建对象了。

抽象类通常作为接口,不涉及到具体实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值