C++学习笔记

C++学习笔记

引用的使用

  • 作为函数的参数,相当于地址传递
	// 函数的引用作为参数
	
void swap(int &a, int &b) {
    int temp;
    temp = a;
    a = b;
    b = temp;
}
  • 作为函数返回的左值
// 函数的返回值不能是局部变量的引用,在cloin中默认不能返回局部变量的引用
int &test() {
    static int c;
    c = 100;
    return c;
}
    int &i = test();
    cout << i << endl;
//    函数作为变量的左值
    test() = 1000;
    cout << i << endl;

在这里插入图片描述

  • 注意以引用作为返回值的函数,不能返回局部变量的引用,原因,在函数体内部,创建的变量是在栈区生成,当函数执行完毕后,将会销毁
  • 引用常量:const int &b 定义的变量,不能够改变b指向的值
int test1(const int &b) {
    int c = 1 + b;
    return c;
}

类的定义

  • 通过点与圆的圆心的距离案例
  • 定义点类
    Point.h
#include <iostream>
using namespace  std;
#include <string>
class Point {
public:
   int getX() const;

   void setX(int x);

   int getY() const;

   void setY(int y);

   Point();

   Point(int x, int y);

   Point(const Point &point);

   virtual ~Point();

private:
   int x;
   int y;
};

Point.cpp

#include "Point.h"

int Point::getX() const {
    return x;
}

void Point::setX(int x) {
    Point::x = x;
}

int Point::getY() const {
    return y;
}

void Point::setY(int y) {
    Point::y = y;
}

Point::Point() {}

Point::Point(int x, int y) {
    cout<<"Point的有参构造函数执行"<<endl;
    Point::x = x;
    Point::y = y;
}

Point::Point(const Point &point) {
    cout<<"Point的拷贝构造函数执行"<<endl;
    Point::x = point.getX();
    Point::y = point.getY();
}

Point::~Point() {
    cout << "Point析构函数执行"<<endl;
}
  • 拷贝构造函数的定义(定义引用常量)
Point::Point(const Point &point) {
    cout<<"Point的拷贝构造函数执行"<<endl;
    Point::x = point.getX();
    Point::y = point.getY();
}

Circle.h的定义

#include "Point.h"
#include <iostream>
using namespace  std;
#include <string>
class Circle {
public:
    Circle(const Point &point, int r);

    Circle();

    Point getPoint() const;

    void setPoint(const Point &point);

    int getR() const;

    void setR(int r);

    virtual ~Circle();

private:
    Point point;
    int r;
};


#endif //C__DOMO_CIRCLE_H

Circle.cpp的定义

//
// Created by Lenovo on 2022/11/4.
//

#include "Circle.h"

Point Circle::getPoint() const {
    return point;
}

Circle::Circle(const Point &point, int r) : point(point), r(r) {
    cout<<"Circle的有参构造函数执行"<<endl;
}

Circle::Circle() {}

Circle::~Circle() {
    cout << "Circle的析构函数执行" << endl;
}

void Circle::setPoint(const Point &point) {
    Circle::point = point;
}

int Circle::getR() const {
    return r;
}

void Circle::setR(int r) {
    Circle::r = r;
}

主函数的编写,main.cpp

#include <iostream>
#include "Point.h"
#include "Circle.h"

using namespace std;

int pow(int a){
    return a*a;
}

bool isCircleInclude(Circle& circle,Point& point){
    int j=pow(circle.getPoint().getX()-point.getX())+pow(circle.getPoint().getY()-point.getY());

    return pow(circle.getR())<=j? true: false;
} 

int main(){

    Point point(10,20);
    Circle circle(point,20);
    Point test(10,20);
    Point newtest(test);
    cout<<newtest.getY()<<" "<<newtest.getX()<<endl;
    bool b = isCircleInclude(circle, test);
//    cout<<bool (b)<<endl;
    return 0;
}

类的对象对象特性

构造函数的调用规则
- 在C++类当中,会默认提供无参构造函数,拷贝构造函数,与析构函数	 
- 如果提供了有参构造函数,则不会提供无参构造函数,但会提供拷贝构造函数
- 如果提供了拷贝构造函数,则不会提供无参构造函数
  • 深拷贝与浅拷贝
    • 对于在类对象内部有指针属性的类,在拷贝构造函数中要采用深拷贝的方式,即在堆区重新申请一片内存空间
    Person(const Person &p){
        this->age=p.age;
        this->height=new int(*p.height);
    }
  • 在析构函数中需要手动将值指针对象删除
 ~Person() {
        if(this->height!= NULL){
            delete this->height;
//            避免出现野指针的情况
            this->height=NULL;
        }
    }
初始化列表
	    Person(int age, int height):age(age),height(new int (height))  {
//        this->age=age;
//        this->height=new int(height);
    }
    Person(const Person &p):age(p.age),height(new int (*p.height)){
//        this->age=p.age;
//        this->height=new int(*p.height);
    }
静态成员变量与静态方法
  • 在编译时分配内存
  • 在类中定义,类外赋值
  • 共享同一个变量
  • 通过对象.变量名 或者类名::变量名 的方法访问静态成员变量
class Person{
    static string address;
};
string Person::address="晋中市";
       cout<<p.address;
        cout<<Person::address;
  • 静态方法中只能访问静态成员变量
    static void func(){
        cout<<"静态成员方法"<<endl;
        cout<<"地址是"<<Person::address;
    }
  • 可通过两种方式调用静态方法
 p.func();
    Person::func();

在c++中类的成员变量与成员方法是分开存储的,空对象默认是占据一个字节的空间

this指针
  • this是指向该对象的指针,*this代表的就是该对象
  • this可以解决命名冲突的问题
  • this指针可以解决成员函数需要返回本对象的指针的问题(链式编程)
//    实现两者年龄的相加
    Person& addage(Person& p){
        this->age+=p.age;
        return *this;
    }
    int age;
    int *height;
    static string address;
};

int main() {

    Person p1(10,20);
    Person p2(p1);
    p2.addage(p1).addage(p1).addage(p1);
    cout<<p2.age<<endl;
    return 0;
    

在这里插入图片描述
注意:为什么addage函数的返回值需要加&?
理由:如果不加&,代表该函数返回的是一个新的对象,而不是原先的对象,添加了&符号,相当于给原有的对象,添加了别名,在使用链式编程时,可以一值对原对象进行操作

常对象与常函数
 void test01() const{
        this->age=10;
        cout<<"常函数";
    }
    mutable int age;
  • 在常函数中不能修改成员变量的值,但是如果成员变量添加了mutable 关键字,在常函数中可以修改,这个变量叫做常变量

友元

全局函数做友元

    friend void test01();

类做友元

//    类做友元
    friend class GoodGay;

成员函数做友元(在colin中暂未跑通)

// 成员函数做友元
  friend void GoodGay::void ();

继承

继承的基本语法

class html{
public:
    void header(){
        cout<<"头部页面"<<endl;
    }
    void foot(){
        cout<<"尾部页面"<<endl;
    }
    void Fenlei(){
        cout<<"java---python---前端---云计算"<<endl;
    }
};
class Java: public html{
public:
    void content(){
        cout<<"java页面"<<endl;
    }
};
class Python: public html{
public:
    void content(){
        cout<<"python页面"<<endl;
    }
};


int main() {
    Java java;
    java.header();
    java.Fenlei();
    java.content();
    java.foot();
    cout<<"-----------"<<endl;

    Python python;
    python.header();
    python.Fenlei();
    python.content();
    python.foot();

    return 0;

//    std::cout << "Hello, World!" << std::endl;
    return 0;
}

继承方式

  • public继承:
    • 父类中的public权限在子类中是public
    • 父类中的protect权限在子类中是protect
    • 父类中的private权限在子类中无法访问
  • protect继承
    • 父类中的protect权限与public权限,在子类中可以访问,但在子类中变为保护权限,类外无法访问
    • 父类中的的private权限子类中无法访问
  • private继承
    • 父类中的protect权限与public权限,在子类中可以访问,但在子类中变为私有权限,外部无法访问

继承的对象模型

  • 对于父类中的私有属性,子类也会继承,只不过被编译器隐藏了
class Base{
public:
    int m_A;
protected:
    int m_B;
private:
    int m_C;
};

class SonPublic: public Base{
public:
    void func(){
        this->m_A;//在父类中的公共权限,在之类中扔然是
        this->m_B;//保护权限可以访问
//        this->m_C;//私有权限无法访问
    }
private:
    int m_D;
};

int main() {


    SonPublic sonPublic;
    cout<<"class size is "<<sizeof (sonPublic)<<endl;
    return 0;

//    std::cout << "Hello, World!" << std::endl;
    return 0;
}
  • 运行结果
    运行

继承中构造函数与析构函数的执行顺序

  • 结论:先执行父类的构造函数,在执行子类的构造函数,析构函数的执行顺序相反
class Base {
public:
    Base() {
        cout << "base 的无参构造函数执行" << endl;
    }

    Base(int mA, int mB, int mC) : m_A(mA), m_B(mB), m_C(mC) {
        cout << "base 的有参构造函数执行" << endl;
    }

    virtual ~Base() {
        cout << "base 的析构函数执行" << endl;
    }

public:
    int m_A;
protected:
    int m_B;
private:
    int m_C;
};

// 公共继承
class SonPublic : public Base {
public:
    SonPublic() {
        cout << "SonPublic的无参构造函数" << endl;
    }

    SonPublic(int mA, int mB, int mC, int mD) : Base(mA, mB, mC), m_D(mD) {}

    void func() {
        this->m_A;//在父类中的公共权限,在之类中扔然是
        this->m_B;//保护权限可以访问
//        this->m_C;//私有权限无法访问
    }

    virtual ~SonPublic() {
        cout << "SonPublic的析构函数" << endl;

    }

private:
    int m_D;
};
int main() {


    SonPublic sonPublic;
//    cout << "class size is " << sizeof(sonPublic) << endl;
    return 0;

//    std::cout << "Hello, World!" << std::endl;
    return 0;
}

运行结果
在这里插入图片描述

继承中的同名处理

在这里插入图片描述

class Base {
public:
    Base() {
//        cout << "base 的无参构造函数执行" << endl;
    }

    Base(int mA, int mB, int mC) : m_A(mA), m_B(mB), m_C(mC) {
//        cout << "base 的有参构造函数执行" << endl;
    }

    void func() {
        cout << "父类中的func" << endl;
    }

    virtual ~Base() {
//        cout << "base 的析构函数执行" << endl;
    }
    void  func(int x){
        cout<<"父类中的有参func"<<endl;
    }

public:
    int m_A;
protected:
    int m_B;
private:
    int m_C;
};

// 公共继承
class SonPublic : public Base {
public:
    SonPublic() {
//        cout << "SonPublic的无参构造函数" << endl;
    }

    SonPublic(int mA, int mB, int mC, int mD) : Base(mA, mB, mC), m_A(mD) {}

    void func() {
        cout << "子类中的func" << endl;
    }

    virtual ~SonPublic() {
//        cout << "SonPublic的析构函数" << endl;

    }

public:
    int m_A;
};

int main() {


    SonPublic sonPublic(10, 20, 30, 40);
    cout << "子类中的" << sonPublic.m_A << endl;
    cout << "父类中的" << sonPublic.Base::m_A << endl;
    sonPublic.func();
    sonPublic.Base::func();
    sonPublic.Base::func(10);

//    cout << "class size is " << sizeof(sonPublic) << endl;
    return 0;

//    std::cout << "Hello, World!" << std::endl;
    return 0;
}
  • 运行结果
    在这里插入图片描述

同名静态成员处理

在这里插入图片描述

菱形继承问题

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

在这里插入图片描述


class Aninmel{
public:
    int age;
};
class Sheep: virtual public Aninmel{

};
class Tuo: virtual public  Aninmel{

};
class SheepTuo:  public Sheep,  public Tuo{

};
int main() {

    SheepTuo sheepTuo;
    sheepTuo.Sheep::age=20;

    sheepTuo.Tuo::age=30;
    cout<<"sheepTuo.Sheep::age "<<sheepTuo.Sheep::age<<endl;
    cout<<"  sheepTuo.Tuo::age "<<  sheepTuo.Tuo::age<<endl;
    cout<<"  sheepTuo.age"<<sheepTuo.age<< endl;

    Sheep sheep;
    sheep.age=10;
    cout<<"sheep.age "<<sheep.age<<endl;

//    SonPublic sonPublic(10, 20, 30, 40);
//    cout << "子类中的" << sonPublic.m_A << endl;
//    cout << "父类中的" << sonPublic.Base::m_A << endl;
//    sonPublic.func();
//    sonPublic.Base::func();
//    sonPublic.Base::func(10);

//    cout << "class size is " << sizeof(sonPublic) << endl;
    return 0;

//    std::cout << "Hello, World!" << std::endl;
    return 0;
}

运行结果
在这里插入图片描述

多态

多态的基本语法

  • 地址早绑定,在编译阶段就进行绑定,
class Animel{
public:
   void  speak(){
       cout<<"动物在说话"<<endl;
   }
};

class Cat:public  Animel{
public:
   void speak(){
       cout<<"小猫在说话"<<endl;
   }
};
void test01(Animel& animel){
   animel.speak();

}

int main() {
   Cat cat;
   test01(cat);
//    std::cout << "Hello, World!" << std::endl;
   return 0;
}

在这里插入图片描述

  • 地址晚绑定,在运行阶段进行地址的绑定,将父类中的方法添加virtual关键字,变为虚函数
class Animel{
public:

   virtual void  speak(){
        cout<<"动物在说话"<<endl;
    }
};

在这里插入图片描述

多态原理

在这里插入图片描述

多态案例——计算器类

在这里插入图片描述


class AbstractCalute {

public:
    virtual int getresult() {
        return 0;

    }

    int num1;
    int num2;
};

class AddCalculate : public AbstractCalute {

    int getresult() {
        return num1 + num2;
    }
};

class SpCalculate : public AbstractCalute {

    int getresult() {
        return num1 - num2;
    }
};

class MulCalculate : public AbstractCalute {

    int getresult() {
        return num1 * num2;
    }
};

class ChuCalculate : public AbstractCalute {

    int getresult() {
        return num1 / num2;
    }
};


void test02() {

    AbstractCalute *pCalute = new AddCalculate;
    pCalute->num1 = 10;
    pCalute->num2 = 20;
    cout << "加法结果是" << pCalute->getresult() << endl;
    delete pCalute;

    pCalute = new SpCalculate;
    pCalute->num2 = 20;
    pCalute->num1 = 20;
    cout << "减法结果是" << pCalute->getresult() << endl;

}

int main() {
    test02();
//    std::cout << "Hello, World!" << std::endl;
    return 0;
}

在这里插入图片描述
注意: 在开发中遵循开闭原则,即对扩展开放,对修改关闭

纯虚函数与抽象类

在这里插入图片描述

class AbstractCalute {

public:
    virtual int getresult() =0;

    int num1;
    int num2;
};

多态案例二——饮品制作

class AbatractDrink {
public:
//    注水
    void Bool() {
        cout << "倒水";
    };

//   方材料
    virtual void PutThing() = 0;

// 泡
    virtual void Pao() = 0;

//    倒出饮料
    virtual void Dao() = 0;

    void makedrink() {
        this->Bool();
        this->PutThing();
        this->Pao();
        this->Dao();
    }

};

class Tea : public AbatractDrink {


    void PutThing() override {
        cout << "放入茶叶" << endl;
    }

    void Pao() override {
        cout << "泡茶" << endl;
    }

    void Dao() override {
        cout << "倒茶" << endl;
    }
};


void Drink(AbatractDrink *abatractDrink) {
    abatractDrink->makedrink();
}

void test03(){
    Drink(new Tea);

}
int main() {
    test03();
//    std::cout << "Hello, World!" << std::endl;
    return 0;
}

虚析构函数与纯虚析构函数

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

class AbstractAnimel {
public:
    virtual void speak() = 0;
    virtual ~AbstractAnimel() = 0;

    AbstractAnimel(string *age);

    AbstractAnimel();

    string  *age;
};

AbstractAnimel::~AbstractAnimel() {
    if (this->age== nullptr){
        delete this->age;
        this->age= nullptr;
    }
}

AbstractAnimel::AbstractAnimel(string *age) : age(age) {}

AbstractAnimel::AbstractAnimel() {}

class Cat : public AbstractAnimel {
public:


    Cat(string *name) : name(name) {}

    Cat(string *age, string *name) : AbstractAnimel(age), name(name) {}

    virtual ~Cat() {
        if (this->name != nullptr) {
            delete this->name;
            this->name = nullptr;
        }
    }

public:
    void speak() override {
        cout << *this->age<<" "<<*this->name<<" " <<"猫在叫" << endl;
    }

    string *name;
};

void test04() {
    AbstractAnimel *pCat = new Cat(new string("Animel"),new string("Cat"));
    pCat->speak();

    delete pCat;
}

int main() {
    test04();
//    std::cout << "Hello, World!" << std::endl;
    return 0;
}

多态案例——电脑组装

在这里插入图片描述

// cpu
class Cpu {
public:
    virtual void calculate() = 0;

};

// 存储器
class Memory {
public:
    virtual void Storg() = 0;
};

// 显卡
class VideoCard {
public:
    virtual void Show() = 0;
};

class InetelCpu : public Cpu {
public:
    void calculate() override {
        cout << "Intel Cpu运行" << endl;
    }
};

class LevonMemory : public Memory {
public:
    void Storg() override {
        cout << "联想存储器正在运行" << endl;
    }
};

class LevonVideoCard : public VideoCard {
public:
    void Show() override {
        cout << "显卡正在运行" << endl;

    }
};

class Cpumpter {
public:
    Cpumpter(Cpu *cpu, Memory *memory, VideoCard *videoCard) : cpu(cpu), memory(memory), videoCard(videoCard) {
    }

    virtual  ~Cpumpter();

    void MakeCumpter() {
        this->cpu->calculate();
        this->memory->Storg();
        this->videoCard->Show();
    }

    Cpu *cpu;
    Memory *memory;
    VideoCard *videoCard;
};

Cpumpter::~Cpumpter() {

    if (this->cpu != nullptr) {
        delete this->cpu;
        this->cpu = nullptr;
    }

    if (this->memory != nullptr) {
        delete this->memory;
        this->memory = nullptr;
    }

    if (this->videoCard != nullptr) {
        delete this->videoCard;
        this->videoCard = nullptr;
    }

}

class LevonCpuptor : public Cpumpter {

public:
    LevonCpuptor(Cpu *cpu, Memory *memory, VideoCard *videoCard, const string &name) : Cpumpter(cpu, memory, videoCard),
                                                                                       name(name) {
    }

    virtual ~LevonCpuptor() {
    }

    string name;//电脑名称
};


int main() {

    Cpu *pCpu = new InetelCpu;
    Memory *memory=new LevonMemory;
    VideoCard *videoCard=new LevonVideoCard;

    Cpumpter *cpumpter=new LevonCpuptor(pCpu,memory,videoCard,"联想电脑");
    cpumpter->MakeCumpter();
    delete cpumpter;
//    std::cout << "Hello, World!" << std::endl;
    return 0;
}

二进制文件——写文件

void test01() {
//    创建写文件的流
    ofstream ofs;
    ofs.open("test.txt", ios::app);
    ofs << "张三" << endl;
    ofs << "20" << endl;
    ofs.close();
}

二进制文件——读文件

void test05() {
    Person person(12, "name");
    ofstream ofs("test.txt", ios::binary | ios::out);
    ofs.write((const char *) &person, sizeof(Person));
    ofs.write((const char *) &person, sizeof(Person));
    ofs.write((const char *) &person, sizeof(Person));
    ofs.write((const char *) &person, sizeof(Person));

    ofs.close();

    ifstream ifs("test.txt", ios::binary | ios::in);
    if (!ifs.is_open()) {
        cout << "文件打开失败" << endl;
        return;
    }
    Person temp[5];
    ifs.read((char *) &temp, sizeof(temp));
//    cout<<temp.name<<" "<<temp.age<<endl;

    for (int i = 0; i < 5; ++i) {
        Person temp1 = temp[i];
        cout << temp1.name << " " << temp1.age << endl;
    }
    ifs.close();

}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值