C++ 学习笔记一

150 阅读3分钟

C++和C的区别

C++中引入了类(class)的概念,相当于C中结构体(struct)的升级版,类中的成员不仅可以变量还可以是函数,通过类定义出来的变量称为:对象(Object)

通过类名创建对象的过程称为类的实例化,因此对象也称为类的一个实例(Instance)

image.png

输入输出 cin and cout

// 头文件iostream 包含输入输出对象 cin标准输入 cout标准输出
#include<iostream>

// 声明命名空间 std,后续如果有未指定命名空间的符号,则默认使用 std
using namespace std;

int main()
{
    int x;
    int y;
    // endl表示换行,作用等同于C中的\n
    cout<<"输入x,y"<<endl;
    cin>>x>>y;
    cout<<"x的值为"<<x<<"y的值为"<<y<<endl;
    return 0;
}

内存管理

C++中用new和delete来管理内存,new在堆区分配内存,需要手动释放,因此new和delete应成对出现。

int *a = new int;
delete a;
int *b = new int[1];
delete[] b;

函数重载 Function Overloading

C++中允许多个函数共享相同的名字,但参数列表不能相同,称为函数重载,C++会自动根据输入参数类型选择对应的函数。

#include<iostream>
using namespace std;

//交换int类型变量的值
void Swap(int *a,int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 交换float类型变量的值
void Swap(float *a, float*b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(){
    //交换int类型变量的值
    int n1=100,n2=200;
    Swap(&n1,&n2);
    cout<<n1<<","<<n2<<endl;
    //交换float类型变量的值
    float f1=0.01,f2=0.02;
    Swap(&f1,&f2);
    cout<<f1<<","<<f2<<endl;
}

类和对象

C++的类是一种复杂数据类型的声明,不占用内存空间,对象是类的一个变量,是类这种数据类型创建的数据,因此占用内存空间。

定义成员变量时不能赋值,因为类本身不能占用内存空间,而变量值需要内存来存储。

#include<iostream>
using namespace std;

//定义类,通常在函数外定义
class Student{
    //public表示以下的成员变量和成员函数为公有成员,在程序中可以任意调用
    public:
    //类包含的变量
    char *name;
    int age;
    float score;
    //类包含的函数
    void say(){
        cout<<name<<"的年龄为"<<age<<",成绩为"<<score<<endl;
    }
};

int main(){
    //根据类创建对象
    Student stu;
    stu.name="小明";
    stu.age=15;
    stu.score=92.5f;
    stu.say();

    //对象指针的用法
    Student *pStu=&stu;
    pStu->name="小红";
    pStu->age=18;
    pStu->score=90.2f;
    pStu->say();

    return 0;
}

Student stu;是在栈上创建对象,Student *pstu = new Student;的在堆上创建对象,栈和堆的区别

类体外定义成员函数

除了类体内可以定义成员函数以外,类体外同样可以定义成员函数,类体内定义的成员函数为内联函数,通常不建议使用,因此好的习惯是将函数定义在类体外。

::表示作用域,有三种作用:

  • 类作用域,表明类的变量和函数 Human::setName(char *name)
  • 命名空间作用域,著名所使用的的类和变量属于哪个命名空间 std::cout<<"hello world"<<std::endl;
  • 全局作用域:区分局部和全局函数时使用
//定义类,通常在函数外定义
class Student{
    //public表示以下的成员变量和成员函数为公有成员,在程序中可以任意调用
    public:
    //类包含的变量
    char *name;
    int age;
    float score;
    //类内定义的函数
    void say(){
        cout<<name<<"的年龄为"<<age<<",成绩为"<<score<<endl;
    }
    //类外定义函数(必须先在类内声明)
    void sayout();
};

void Student::sayout(){
    cout<<"类外定义函数"<<endl;
}

类成员访问权限

成员访问限定符

  • public:类外通过对象可以访问public属性的成员
  • protected:类外不可访问
  • private:类外不能访问

类内均可互相访问,项目中的成员变量以及只在类内部使用的成员函数(只被成员函数调用的成员函数)都建议声明为 private。

class Student{
    private//将成员变量命名为m_可以一目了然认出哪个是成员变量
    char *m_name
    
    public:
    void setname(char *name)
};

void Student::setname(char *name){
    m_name=name;
}

int main(){
     Student stu;
     stu.setname("小明");
}

这种情况修改m_name只能通过函数setname,直接用stu.m_name = "小明";是会报错的。

Constructor 构造函数的使用

使用修改private变量若每次都要定义函数类似setname的函数显然非常麻烦,为简化这像工作可以直接使用构造函数在创建对象时就为private变量赋值。(构造函数同样可以重载,创建对象时会根据传递的实参来判断调用哪个构造函数)

#include<iostream>
using namespace std;

class Student{
    private:
        char *m_name;
        int m_age;
        float m_score;
    
    // 声明构造函数
    public:
    Student(char *name, int age, float score);
    
    void show();
};

//定义构造函数
Student::Student(char *name, int age, float score){
    m_name=name;
    m_age=age;
    m_score=score;
}

void Student::show(){
    cout<<m_name<<" "<<m_age<<" "<<m_score<<endl;
}

int main(){
    //创建对象时就向构造函数传参
    Student stu("小明",15,92.5f);
    stu.show();
    return 0;
}

构造函数初始化列表

使用初始化列表可以让代码更简洁(并不能降低运行时间)

Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){
    //TODO:
}

初始化const成员

对于const成员变量初始化列表是唯一的初始化方法。

析构函数

如果使用构造函数为数组分配内存,数组使用完成后应使用析构函数释放内存。

\\定义构造函数
class VLA{
    public VLA(int a);
    ~VLA();//VLA的析构函数
};

this关键字

this是一个const指针,用于访问当前对象的所有成员。

static 静态成员变量

使用静态成员变量可以实现多个对象共享数据。

static int m_total

静态成员变量必须在类外初始化,其占用的是全局的内存而不是单个对象的内存(因此可以被所有对象访问)。

静态成员函数

静态成员函数只能访问静态成员(包括变量和函数)。

静态成员变量/函数通常在统计某个类的所有对象时使用,如下例所示:

class Student{
    public:
    Student(char *name,int age,float score);
    void show();

    //静态成员函数
    public:
    static int getTotal();
    static float getPoints();

    //静态成员变量
    private:
    static int m_total;
    static float m_points;

    private:
    char *m_name;
    int m_age;
    float m_score;
};


//静态变量只能类外初始化
int Student::m_total=0;
float Student::m_points=0.0;

Student::Student(char *name,int age,float score):m_name(name),m_age(age),m_score(score){
    //每建立一个对象更改一次静态变量值
    m_total++;
    m_points+=score;
}

int Student::getTotal(){
    return m_total;
}

float Student::getPoints(){
    return m_points;
}

友元函数

友元函数本身是全局函数,在类中用friend关键字指明,这类函数可以任意访问类中的private成员。