C++语法进阶

类与对象

class A{
private:
    int i;
public:
    void f();
};

void A::f()
{
    i=10;
    cout<<i;
}

int main()
{
    A a;
    a.f();
    return 0;
}
class A{
public:
    int i;
    void f();
};

void A::f()
{
    i=10;
    cout<<i<<endl;
}

void f(struct A* p)//指针传入类A对象a的地址
{
    p->i=20;
    cout<<p->i<<endl;
}

int main()
{
    A a;
    a.f();
    cout<<a.i<<endl;
    f(&a);
    cout<<a.i<<endl;
    return 0;
}

动态制造对象(new & delete)

相当于C语言的malloc和free

在这里插入图片描述

class A{
    int i;
public:
    A(){i=0;cout<<"A::A()"<<endl;}
    ~A(){cout<<"A::~A(),i="<<i<<endl;}
    void set(int i){this->i=i;cout<<"i="<<i<<endl;} //调用这个函数对象的i,或者(int ii)i=ii
    void f(){cout<<"hello";}
};

int main()
{
    A *p = new A[10];
    for(int i=0;i<10;i++)
    {
        p[i].set(i);
    }
    delete[] p;
    return 0;
}

访问权限

  • public:公开的,任何人可以访问

  • private:私有的,只有这个类的成员函数可以访问这些成员变量或成员函数,同一个类的对象之间可以访问

  • protected:只有这个类自己和它的子孙可以访问

  • 不去限制访问属性时,class是private,struct是public

  • 友元函数是可以直接访问类的私有成员的非成员函数。

  • 需要在类的定义中加以声明

  • 在调用时不能通过对象调用。也没有this指针。

  • 友元函数也可以在类内声明,在类外定义。

```
struct X; //前项声明,告诉编译器X是个东西

struct Y{
    void f(X*);
};

struct X{
private:
    int i;
public:
    void initialize();
    friend void g(X*,int);
    friend void Y::f(X*);
    friend struct Z;
    friend void h();
};

void X::initialize(){
    i=0;
}

void g(X*x,int i){
    x->i=i;
}

void Y::f(X*x){
    x->i=44;
}

struct Z{
private:
    int j;
};
```

<img src="C:\Users\清昀\AppData\Roaming\Typora\typora-user-images\1692539543617.png" alt="1692539543617" style="zoom:80%;" />

继承

继承与派生:保持已有类的特征构造新类的过程为继承,在已有类的基础上新增特性而产生新类的过程称为派生

class A{
public:
    A():i(0) {cout<<"A::A()"<<endl;} //i(0)初始化i=0
    ~A() {cout<<"A::~A()"<<endl;}
    void print(){cout<<"A::f()"<<i<<endl;}
    void set(int ii){i=ii;}
private:
    int i;
};

class B : public A{ //B是A的子类

};
int main()
{
    B b;
    b.set(10);
    b.print();
    return 0;
}

在这里插入图片描述

class A{
public:
    A(int ii):i(ii) {cout<<"A::A()"<<endl;} //i(0)初始化i=0
    ~A() {cout<<"A::~A()"<<endl;}
    void print(){cout<<"A::f()"<<i<<endl;}
    void set(int ii){i=ii;}
private:
    int i;
};

class B : public A{ //B是A的子类
public:
    B() : A(15){cout<<"B::B()"<<endl;} //调用A的构造函数给它参数
    ~B() {cout<<"B::~B()"<<endl;}
    void f(){
        set(20);
        print();
    }
};
int main()
{
    B b;
    b.f();
    return 0;
}

在这里插入图片描述

函数重载

可以将语义、功能相似的几个函数用同一个名字表示,但参数不同(包括类型、顺序不同),即函数重载
1)相同的范围(在同一个类中);
2)函数名字相同;
3)参数不同;

内联函数

为了消除函数调用的时空开销,C++ 提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,类似于C语言中的宏展开。这种在函数调用处直接嵌入函数体的函数称为内联函数(Inline Function),又称内嵌函数或者内置函数。 不会出现在最终的可执行代码里,只是会存在于编译器中,在编译器需要的地方插入。

函数小,循环被调用适合inline

class a
{
private:
    int i;
public:
    a();
    void f1();
};
 
inline a::a() 
{
...
}
inline void a::f1()
{
...
}

const与重载

在这里插入图片描述

const指针:它所指的对象不能通过它修改

class A{
    int i;
public:
    A():i(0){}
    void f() {cout<<"f()"<<endl;}
    void f() const {cout<<"f()const"<<endl;}
};

int main()
{
    const A a; //a是const
    a.f();
    return 0;
}

在这里插入图片描述

构成overload重载关系

引用

定义时必须初始化

int main()
{
    int x=3;
    int& y = x;//y是x的引用(别名)
    const int& z=x;//不能通过z对x的改变
    cout<<"x="<<x<<endl;
    cout<<"y="<<y<<endl;
    cout<<"z="<<z<<endl;
    y=9;
    cout<<"x="<<x<<endl;
    cout<<"y="<<y<<endl;
    cout<<"z="<<z<<endl;
    return 0;
}
  • 指针与引用

    int* f(int* x){ //传统指针写法,改变&x数据返回指针
        (*x)++;
        cout<<*x<<endl;
        return x;
    }
    
    int& g(int& x){ //引用写法,返回一个int的引用(reference)
        x++;
        return x;
    }
    
    int x;
    
    int& h(){ //一个函数的返回结果是reference,故能作为左值被赋值
        return x; //让x变量变成reference返回
    }
    int main()
    {
        int a = 0;
        cout<<f(&a)<<endl;
        cout<<g(a)<<endl;
        h() = 16;
        cout<<"x="<<x<<endl;
        return 0;
    }
    

在这里插入图片描述

子类父类

uocast:子类的对象被当作父类的对象看待

class A{
public:
    int i;
    A():i(10){}
};

class B:public A{
private:
    int j;
public:
    B():j(50) {}
    void f() {cout<<"B.j="<<j<<endl;}
};

int main()
{
    A a;
    B b;
    cout<<a.i<<" "<<b.i<<endl;
    cout<<sizeof(a)<<" "<<sizeof(b)<<endl;
    int *p = (int*)&a;
    cout<<p<<" "<<*p<<endl;
    *p = 20;
    cout<<a.i<<endl;
    p=(int*)&b;
    cout<<p<<" "<<*p<<endl;
    p++;
    *p = 60; //改变j的值
    cout<<p<<" "<<*p<<endl;
    b.f();
    return 0;
}

多态

1 必须通过基类的指针或者引用调用虚函数
2 被调用的函数是虚函数,且必须完成对基类虚函数的重写

class A{
public:
    A():i(10){}
    virtual void f() {cout<<"A::f()"<<i<<endl;}
    int i;
};

int main()
{
    A a,b;
    a.f();
    cout<<sizeof(a)<<endl;
    int *p = (int*)&a;
    int *q = (int*)&b;
    cout<<*(p+1)<<endl; //这个才是i的值
    cout<<*p<<endl;//地址相同
    cout<<*q<<endl;
    return 0;
}

在这里插入图片描述

通过指针或引用去调用virtual函数才是动态绑定

class A{
public:
    A():i(10){}
    virtual void f() {cout<<"A::f()"<<i<<endl;}
    int i;
};

class B:public A{
public:
    int j;
    B():j(20) {}
    virtual void f() {cout<<"B::f()"<<j<<endl;}
};

int main()
{
    A a;
    B b;
    A *p = &a;

    int* r = (int*)&a;
    int* t = (int*)&b;
    *r = *t; //让a的一块内存指向b的
    p->f(); //在a里找j的不存在的内存,故不存在
    //p->f(); //调用B的f()
    //a=b; //把b的值给了a
    //p=&a;
    //p->f();
    return 0;
}

override覆盖

override表示函数应当重写基类中的虚函数(用于派生类的虚函数中)。

重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数名各不相同(即参数个数或类型不同)。
重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了

  • 覆盖是存在类中,子类重写从基类继承过来的函数。但是函数名、返回值、参数列表都必须和基类相同。

  • 当子类的对象调用成员函数的时候,如果成员函数有被覆盖则调用子类中覆盖的版本,否则调用从基类继承过来的函数

  • 如果子类覆盖的是基类的虚函数,可以用来实现多态。

  • 当子类重新定义基类的虚函数之后,基类指针可以根据赋给它不同子类指针动态的调用子类中的虚函数,可以做到动态绑定,这就是多态。

引用plus

void f(const int& i)
{
    cout<<i<<endl;
}

int main()
{
    int i=3;
    f(i*3);
    return 0;
}

static

1.静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
2.非静态成员函数可以任意地访问静态成员函数和静态数据成员;
3.静态成员函数不能访问非静态成员函数和非静态数据成员;
4.调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以用类名::函数名调用(因为他本来就是属于类的,用类名调用很正常)

class Rectangle
{
private:
	int m_w,m_h;
	static int s_sum;

public:
	Rectangle(int w,int h)
	{
		this->m_w = w;
		this->m_h = h;
		s_sum += (this->m_w * this->m_h);
	}

	static void GetSum()  //这里加上static
	{
		cout<<"sum = "<<s_sum<<endl;
	}


};
int Rectangle::s_sum = 0;  //初始化

int main()
{
	cout<<"sizeof(Rectangle)="<<sizeof(Rectangle)<<endl;
	Rectangle *rect1 = new Rectangle(3,4);
	rect1->GetSum();
	cout<<"sizeof(rect1)="<<sizeof(*rect1)<<endl;
	Rectangle rect2(2,3);
	rect2.GetSum();  //可以用对象名.函数名访问
	cout<<"sizeof(rect2)="<<sizeof(rect2)<<endl;
	Rectangle::GetSum();  //也可以可以用类名::函数名访问
	return 0;
}

在这里插入图片描述

  • 静态全局变量
class A{
public:
    A(){i=0;}
    void print() {cout<<i<<endl;}
    void set(int ii) {i=ii;}
//private:
    static int i; //只有声明,需要定义 //作为一个成员的全局变量
};

int A::i = 20; //有static需要这里的定义

int main()
{
	A a,b;
	a.set(10);
	b.print();
	cout<<a.i<<endl<<A::i<<endl;
	return 0;
}
  • 静态函数

    class A{
    public:
        A(){i=0;}
        void print() {cout<<i<<endl;}
        void set(int i) {this->i=i;}
        static void say(int ii){cout<<ii<<i<<endl;}
        static int i; //只有声明,需要定义 //作为一个成员的全局变量
    };
    
    int A::i; //有static需要这里的定义
    
    int main()
    {
    	A a,b;
    	a.set(10);
    	b.print();
    	cout<<a.i<<endl<<A::i<<endl;
    	A::say(10);//在创建对象前可以访问静态函数
    	a.say(20);
    	return 0;
    }
    

operator运算符重载

在这里插入图片描述
在这里插入图片描述

class person
{
private:
    int age;
public:
    person(int nAge)
    {
        this->age = nAge;
    }

    bool operator*(const person& ps) //重载*运算符
    {
        if (this->age == ps.age)
        {
            return true;
        }
        return false;
    }
    void print(){cout<<age<<endl;}
};

int main()
{
    person p1(10);
    person p2(10);
    if (p1 * p2)
    {
        cout << "p1 is equal with p2." << endl;
    }
    else
    {
        cout << "p1 is not equal with p2." << endl;
    }
    return 0;
}

模板

  • 函数模板

    template <class 类型参数1, class类型参数2, ...>
    返回值类型  模板名(形参表)
    {
        函数体
    }
    
    template<class T>
    void Swap(T & x, T & y)
    {
        T tmp = x;
        x = y;
        y = tmp;
        cout<<x<<" "<<y<<endl;
    }
    int main()
    {
        int n = 1, m = 2;
        Swap(n, m);  //编译器自动生成 void Swap (int &, int &)函数
        double f = 1.2, g = 2.3;
        Swap(f, g);  //编译器自动生成 void Swap (double &, double &)函数
        return 0;
    }
    
  • 编译器由模板自动生成函数的过程叫模板的实例化。由模板实例化而得到的函数称为模板函数。

vector

https://blog.csdn.net/fckbb/article/details/130849188

  • vector模板C++标准库中的一个容器类,被设计为动态数组,即它可以根据需要自动分配内存空间来存储元素。 vector模板的本质是一个****类模板**** , vector类使用****连续的内存****来存储元素

定义方式:vector<数据类型>名称

  void Swap(T & x, T & y)
  {
      T tmp = x;
      x = y;
      y = tmp;
      cout<<x<<" "<<y<<endl;
  }
  int main()
  {
      int n = 1, m = 2;
      Swap(n, m);  //编译器自动生成 void Swap (int &, int &)函数
      double f = 1.2, g = 2.3;
      Swap(f, g);  //编译器自动生成 void Swap (double &, double &)函数
      return 0;
  }
  
  • 编译器由模板自动生成函数的过程叫模板的实例化。由模板实例化而得到的函数称为模板函数。

vector

https://blog.csdn.net/fckbb/article/details/130849188

  • vector模板C++标准库中的一个容器类,被设计为动态数组,即它可以根据需要自动分配内存空间来存储元素。 vector模板的本质是一个****类模板**** , vector类使用****连续的内存****来存储元素

定义方式:vector<数据类型>名称

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值