C++基础知识整理

本文围绕C++展开,详细介绍了封装机制,包括访问控制符、友元、重载、静态成员、构造与析构函数等;阐述了虚函数的使用,如虚函数列表、重写、多态、纯虚函数和抽象类;还讲解了继承概念,包含继承的访问控制、单继承、多继承和虚继承等内容,有助于提升代码安全性和可维护性。

1. 封装

在C++中,封装是一种将数据和操作数据的函数封装在一起的机制。它可以将数据隐藏起来,只提供公共接口给外部使用,从而保证数据的安全性和一致性。

封装的目的是将数据和相关操作封装在一起形成一个类,对外部使用者隐藏内部的实现细节。这样做的好处是可以隐藏数据的具体实现,提高代码的安全性和可维护性。

在C++中,封装主要通过类和访问控制来实现。类将数据成员和成员函数封装在一起,通过访问控制符(public、private、protected)来控制成员的访问权限。数据成员通常被声明为私有(private),只能通过公有(public)的成员函数来访问、修改数据

权限 类内 类外 派生类
public 可以访问 可以访问 可以访问
protected 可以访问

不可访问

可以访问父类的
private 可以访问

不可访问

不可访问

封装的优点包括:

  1. 隐藏实现细节:封装使得实现细节对外部使用者不可见,只提供了一个抽象的接口。这样可以避免外部使用者了解或依赖于具体的实现细节,提高代码的安全性和可维护性。

  2. 简化接口:通过封装,可以将一组相关的数据和操作组织在一起,形成一个类。外部使用者只需要使用类提供的公共接口,而不需要了解内部的实现细节,从而简化了接口的使用。

  3. 提高代码复用性:类可以被多次实例化,每个实例都具有相同的数据结构和操作方法。这样可以提高代码的复用性,避免了重复编写相同功能的代码。

  4. 隔离变化:封装可以将类的实现细节与外部使用者分离开来,使得变化的影响范围最小。当类的实现发生变化时,只需要修改类的内部,而不需要修改外部使用者的代码。

总之,封装是C++中一种重要的特性,可以提高代码的安全性、可维护性和复用性。通过合理的封装,可以隐藏实现细节,简化接口,并隔离变化,使得代码更加健壮和可扩展。

1> 访问控制符,封装中的护城河

C++访问控制符用于控制类的成员(包括变量和函数)的访问权限,包括三种控制符:

  1. public: 公有控制符,表示成员可以在类的内部和外部进行访问。任何地方都可以访问公有成员。

  2. private: 私有控制符,表示成员只能在类的内部进行访问,外部无法直接访问私有成员。可以通过类的公有成员函数来间接访问私有成员。

  3. protected: 保护控制符,类似于私有控制符,表示成员只能在类的内部进行访问,外部无法直接访问保护成员。不同的是,派生类可以直接访问基类的保护成员

通过访问控制符,可以实现类的封装性和数据隐藏。公有成员提供给外部访问,私有成员只能在类内部使用,保护成员提供给派生类使用。这样可以防止外部直接修改类的私有成员,从而提高类的安全性和数据的完整性。

C++类中的默认控制符是private,与之区分的是C中的struct,它的默认控制符是public。

2> friend 封装中的双刃剑

在C++中,友元(friend)是一种特殊的函数或类,它可以访问另一个类中的私有成员。友元函数或类可以在被访问的类中声明为友元,从而被授权访问私有成员。

友元函数在类声明中使用关键字"friend"声明,如下所示:

class MyClass {
public:
    MyClass(int num) : number(num) {}
    
    friend void friendFunction(MyClass& obj);
    
private:
    int number;
};

void friendFunction(MyClass& obj) {
    // 可以访问MyClass中的私有成员
    std::cout << "Private member of MyClass accessed: " << obj.number << std::endl;
}

在这个例子中,friendFunction函数被声明为MyClass的友元函数,因此它可以直接访问MyClass中的私有成员number。

友元类的声明方式类似于友元函数,只是将类名作为关键字"friend"后的参数,如下所示:

class MyClass {
public:
    MyClass(int num) : number(num) {}
    
    friend class FriendClass;
    
private:
    int number;
};

class FriendClass {
public:
    void accessPrivateMember(MyClass& obj) {
        // 可以访问MyClass中的私有成员
        std::cout << "Private member of MyClass accessed: " << obj.number << std::endl;
    }
};

在这个例子中,FriendClass被声明为MyClass的友元类,因此它可以直接访问MyClass中的私有成员number。

需要注意的是,友元函数或类的声明并不属于类的成员函数或成员类。因此,在使用友元函数或类时,应在类的声明中将其声明为友元,而在类的实现中定义和实现它们。

3> 重载 封装中的套路

C++中的重载(Overload)是指在同一个作用域内,可以定义多个同名函数,但其参数列表必须不同。重载的函数可以根据不同的参数类型和个数进行调用,使得程序具有更灵活的使用性。

C++中函数的重载可以通过以下几种方式实现

    1. 参数个数不同:函数名相同,但参数个数不同,可以实现重载。例如:

void foo(int x);
void foo(int x, int y);

    2. 参数类型不同:函数名相同,但参数类型不同,可以实现重载。例如:

void foo(int x);
void foo(double x);

    3. 参数顺序不同:函数名相同,但参数类型相同,但参数顺序不同,可以实现重载。例如:

void foo(int x, double y);
void foo(double y, int x);

    4. 常量性不同:函数名相同,但参数类型相同,但其中一个函数是const成员函数,可以实现重载。例如:

class MyClass {
public:
    void print() const;
    void print();
};

需要注意的是,重载函数的返回类型并不参与函数重载的判断

当调用一个重载函数时,编译器会根据函数调用时的实参类型和个数,选择最合适的重载函数进行调用。如果存在多个重载函数都能匹配调用参数,编译器会进行一系列的匹配规则判断,选择最佳匹配的重载函数。

重载函数的命名应该尽量清晰和准确,以避免产生歧义和误导。同时,在使用重载时,需要注意函数调用的实参类型和个数,确保调用的重载函数是符合预期的。

4> 静态成员

C++中的静态成员是类的成员,与类的实例对象无关,它被所有的类实例共享。而非静态成员是每个类实例独有的。

静态成员可以是静态变量或静态函数。

静态变量: 静态成员变量在类声明中以static关键字定义

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值