C语言与C++的区别总结

头文件-注释-名字空间

#include <cstdio>//不用 <*.h>形式
#include <iostream>//输入输出流
using namespace std;//标准库的名字空间
using X::name;//使用X名字空间的单个名字name
   

名字空间 namespace

namespace first {
    int a;
    void f(){/**/}
}

int main() {
    first::a = 3;//使用first名字空间
}

输入输出流

#include <iostream>
using namespace std;
int main(){
    int n;
    cin >> n;//输入
    cout << "Hello World!" << endl;//输出
    return 0;
}

变量及其作用域

  • 变量可以随时定义
  • { }表示一个作用域,在这个程序块中的变量是局部变量
  • ::a 表示在局部作用域里访问全局同名变量a

引用

类似C语言的指针用法,引用符**&** 给一个变量起了另一个名字,在函数中被引用的形参与实参是同一个变量,可以在函数中被修改。

内联函数和异常处理

内联函数

  • 函数定义前面加上 inline 关键字,如

    inline int distance(}{/**/}
    
  • 内联函数用于不含循环的函数,在被调用时直接用函数体替换。没有形参与实参的传递开销。

异常处理

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

    try {
        if (a > 100) throw 100;
        if (a < 10) throw 10;
        throw a / 3;
    }
    catch (int result) {
        cout << "Result is:" << result << endl;
    }
    catch(...) {
        cout << "其他所有异常都在这里捕获" << endl;
    }
    
  • 实际编程中少用

函数的默认参数

  • 默认形参,必须一律在最右边

    double test(double a, double b = 7){/**/}
    

函数重载、运算符重载

函数重载

  • C++允许函数同名,只要它们的形参不一样(个数或者对应参数的类型)
  • 调用函数时将根据实参和形参的匹配选择最佳函数,如果有多个难以区分的最佳函数,则变化一起报错!
  • 不能根据返回类型区分同名函数

运算符重载

ElemType operater +[-*/] (ElemType a, ElemType b) {
    /**/
    return result;
}//重新定义特殊类型的运算符,比如向量的点乘、叉乘、数乘。

模板函数 template

  • 模板template函数:厌倦了对每种类型求最小值(针对同一功能,要满足多种数据类型)
template<class Type>//Type为一个模板类型
Type minValue(Type a, Type b) {
    if (a < b) return a;
    else return b;
} 
//自动生成一个针对该数据类型的具体函数
  • 不同类型参数

    template<class Type1, class Type2>
    Type1 minValue(Type1 a, Type2 b) {
    	if (a < b) return a;
    	else return (Type1)b;
    }
    
    

动态分配内存的new 和 delete

  • new 对应 malloc
  • delete 对应 free
dp = new double;//返回一个指向double类型的指针
delete dp;//释放一个double大小的内存

dp = new double[n];//新建一个指向一块double类型的内存,并返回首地址指针
delete[] dp;//释放一整块内存

类的定义

  • 类是在C的struct类型上,增加了成员函数。

  • C++使得struct不但包含数据,还包含函数(方法)用于访问或修改类变量(对象)的特性。

    struct date {
        int year,month,day;
        void print() {
            cout << year << '-' << month << '-' << day << endl;
        }
    }//这是一个简单的C++类
    
    

自引用、成员函数重载运算符

自引用

  • 成员函数返回“自引用” (*this)

    struct date {
        int year,month,day;
        void print() {
            cout << year << '-' << month << '-' << day << endl;
        }
        date & add(int d) {
            day = day + d;
            return *this;//this是指向调用这个函数的类型对象指针
            			//*this就是调用这个函数的那个对象
            			//这个成员函数返回的是“自引用”,即调用这个函数本身
            			//通过返回自引用,可以连续调用这个函数
            			//Day.add(3);
            			//Day.add(2).add(7);
        }
    }
    
    

成员函数重载运算符

struct date {
    int year,month,day;
    void print() {
        cout << year << '-' << month << '-' << day << endl;
    }
    date & operator+=(int d) {
        day = day + d;
        return *this;//this是指向调用这个函数的类型对象指针
        			//*this就是调用这个函数的那个对象
        			//这个成员函数返回的是“自引用”,即调用这个函数本身
        			//通过返回自引用,可以连续调用这个函数
        			//Day.add(3);
        			//Day.add(2).add(7);
    }
}

构造函数和析构函数

构造函数

struct date {
    int year,month,day;
    void print() {
        cout << year << '-' << month << '-' << day << endl;
    }
    date(int dd,int mm,int yy) {
        day = dd;
        month = mm;
        year = yy;
    }//类似的函数名字与类名一致,并且没有返回类型的函数,称为构造函数。
    //构造函数在我们定义一个类的对象时,会被自动调用。
}

析构函数

struct date {
    int year,month,day;
    void print() {
        cout << year << '-' << month << '-' << day << endl;
    }
    date(int dd,int mm,int yy) {
        day = dd;
        month = mm;
        year = yy;
    }//类似的函数名字与类名一致,并且没有返回类型的函数,称为构造函数。
    //构造函数在我们定义一个类的对象时,会被自动调用。
    
    virtual ~date() {//析构函数不需要参数
        delete[] name;//析构函数释放之前申请的内存,防止内存泄漏
    }
}

访问控制与接口

  • 将struct类型改为class类型(class定义的类的成员默认都是私有的private,外部函数无法通过类对象成员或类成员函数)
  • 想要在class中定义可以控制的接口,需要加上关键字 public: 表示公开的。
  • 若要改变private的成员,需要在接口处定义函数修改。
  • 接口:public的公开成员,(一般是成员函数),称为这个类的对外接口,外部函数只能通过这些类接口访问类对private等非public的包含内部细节,不对外公开,从而可以封装保护类对象。

拷贝构造函数和赋值运算符

  • 拷贝构造函数:定义一个类对象时用同类型的另外对象初始化

    struct student{/**/}
    student a;
    student b(a);//b是拷贝构造函数,默认的拷贝构造函数是一种硬拷贝,并没有新分配内存
    			//遇到多次析构函数会报错
    			//解决办法是在结构体中自定义拷贝构造函数,
    
    
  • 赋值运算符:一个对象赋值给另一个对象

类体外定义成员函数(方法)

  • 必须在类定义中声明,类体外要有类作用域,否则就是全局外部函数了!

    class student {
    public:
        void print();//在类体内只声明
    }
    
    void student::print() {//在类体外定义时加上类作用域
        cout << "Hello World!" << endl;
    }
    
    

类模板

  • 我们可以把一个类变成一个“类模板”或“模板类”,正如一个模板函数一样。

  • 例如:将原来所有的double换成模板类型Type,并加上模板头 template

    template <class T>
    class Array {
        int size;
        T *data;
    }
    int main(){
        Array<double> t[10];//用double代替类模板里的T
        Array<string> s[10];
    }
    
    

类型别名typedef

typedef int INT

String和Vector、继承与派生、虚函数和纯虚函数

  • string对象的初始化

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        string s1;
        string s2("hello");
        s1 = "Hello";
        string s3(s1);//拷贝构造函数, string s3 = s1;
        string s4("This is a C_string",10);//取前10个字符构成字符串
        string s5(s4,6,4);//从s4中第6个字符开始取4个构成字符串
        string s6(10,'*');//由15个‘*’构成的字符串
        string s7(s4.begin(),s4.end() - 5);
        string s8 = "Hello";
        string s9 = s1 + "hello" + s2;
    }
    
    
  • string对象的长度: s.size()

  • vector

    #include <vector>
    #include <iostream>
    using namespace std;
    
    int main() {
        vector<double> student_marks;
        student_marks.resize(10);//此语句用于重新定义向量的大小,默认为0
        
        for (vector<double>::sizetype i = 0; i < num_students; i++) {/**/}//赋值
        //vector<double>::sizetype i 更安全
        for (vector<double>::iterator it = student_marks.begin(); 
            it != student_marks.end(); it++) {
            cout << *it << endl;
        }
        return 0;
    }
    
    

    派生类

    • Inheritance继承(Derivation派生):一个派生类(deived class)从1个或多个父类(parent class) / 基类(base class)继承,即继承父类的属性和行为,但也有自己的特有属性和行为。

      class Employee {/**/}
      
      class Manager: public Employee {/**/}//Manager继承了Employee的类,但也有自己特有的属性
      
      
    • 初始化成员列表

      Employee::Employee(string n):name(n){}
      //表示传入一个参数n,并将n赋值给成员name
      Manager::Manager(string n; int l):Employee(n),level(l){}
      //给基类Emlpoyee传入n参数,将l赋值给level成员
      
      
    • 派生类的构造只能描述它自己的成员和其直接基类的初始式,不能去初始化基类的成员

    虚函数和多态

    • 派生类的指针可以自动转化为基类指针,用一个指向基类的指针分别指向基类对象和派生类对象,因此,可以把所有基类以及派生类的对象的指针都放在一起便于管理
    • 基类和派生类的同名函数有不同的功能时,需要在基类中该函数前加上关键字 virtual 表示为虚函数,(派生类可加可不加),这样就可以根据不同的指针调用不同派生类中的不同函数,产生的现象叫 多态性

    多重继承和多重派生

    • 我们可以从一个类派生出多个不同的类

    • 也可以从多个不同的类派生出一个类,多重派生

      class one{}
      class two{}
      class mul:public one,public two
      
      

    纯虚函数和抽象类

    • 纯虚函数(pure virtual function)和 抽象类(abstract base class)

    • 函数体=0的虚函数称为纯虚函数。包含纯虚函数的类称为抽象类

      virtual const char * speak() = 0;//speak()是一个纯虚函数
      
      
    • 抽象类不能实例化(不能定义抽象类的对象/变量)

    • 从抽象类派生的类型如果没有继承实现所有的纯虚函数,则仍然是抽象类

      class Cow:public Animal {
      public:
          Cow(std::string name):Animal(name){}
          virtual const char* speak(){return "Moo";}//实现了纯虚函数,不再是抽象类
      }
      
      
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值