C++学习笔记——私有继承、多重继承、类模板

 

目录

一、私有继承

二、多重继承

三、类模板

四、一个使用私有继承的示例代码

4.1代码

4.2输出结果

五、多重继承案列

六、类模板案例


C++中的继承和模板是非常强大和灵活的特性,它们可以帮助我们实现代码复用、抽象和泛化等目标。本文将着重介绍私有继承、多重继承和类模板这三个C++中比较重要的特性。

一、私有继承

私有继承是一种比较特殊的继承方式,它在语法上与公有继承和保护继承没有太大区别,但是其继承关系所暴露的接口和成员变量都会被隐藏起来,只有派生类自己可以访问到基类的成员。在使用私有继承时,我们通常会借助基类指针或引用来访问基类的成员,而不会直接使用派生类对象。

私有继承的应用场景比较广泛,例如可以用来实现“has-a”关系、模块化设计等。具体来说,如果一个类需要另一个类的部分功能,但是不想公开其接口,可以使用私有继承。此外,私有继承也可以用来防止基类的成员被误操作或滥用,从而提高代码的安全性。

二、多重继承

多重继承是C++中比较复杂和容易出现问题的特性之一,它允许一个派生类同时继承多个基类。多重继承在语法上并不复杂,但是在设计和实现上需要考虑一些问题,例如可能会出现菱形继承问题、基类构造函数的调用顺序等。因此在使用多重继承时需要谨慎考虑其适用性和实现细节。

多重继承的应用场景也比较广泛,例如可以用来实现多态、功能组合等。具体来说,如果一个类需要具有多种不同的特性或行为,可以使用多重继承来组合多个基类。此外,多重继承也可以用来实现接口继承和实现继承的分离,从而更好地实现面向对象的编程思想。

三、类模板

类模板是C++中非常强大和灵活的特性,它允许我们通过一个通用的模板来生成多个具体的类。类模板在定义时需要指定模板参数,这些参数可以是类型、常量、模板等等。类模板可以用来实现泛型编程、容器和算法库等。

类模板的语法比较复杂,但是理解一些基本概念后就可以轻松地应用它们。例如,我们可以使用模板参数来定义成员变量和成员函数,或者使用特化(partial specialization)和偏特化(full specialization)来针对不同的情况实现不同的行为。此外,C++11及以上版本还提供了可变参数模板(variadic template)和模板别名(template alias)等新特性,使得类模板的应用更加灵活和便捷。

 

私有继承是指派生类以 private 访问权限继承基类的成员。这意味着派生类无法直接访问基类的成员,只能通过基类指针或引用来访问。

四、一个使用私有继承的示例代码

4.1代码

#include <iostream>

class Base {
public:
    void display() {
        std::cout << "Base class" << std::endl;
    }
};

class Derived : private Base {
public:
    void showMessage() {
        display();  // 通过基类指针访问基类的成员函数
    }
};

int main() {
    Derived derived;
    derived.showMessage();
    return 0;
}

在这个示例中,Derived 类私有继承 Base 类。Derived 类中的 showMessage() 函数通过基类指针调用了 Base 类的 display() 函数。

4.2输出结果

Base class

私有继承主要用于实现类与类之间的“has-a”关系,即一个类包含另一个类的对象作为其成员。

五、多重继承案列

多重继承是指派生类可以同时继承多个基类。在多重继承中,派生类可以分别指定不同的继承方式(public、protected 或 private)来控制基类成员的访问权限。

下面是一个使用多重继承的示例代码:

#include <iostream>

class Base1 {
public:
    void display1() {
        std::cout << "Base1 class" << std::endl;
    }
};

class Base2 {
public:
    void display2() {
        std::cout << "Base2 class" << std::endl;
    }
};

class Derived : public Base1, private Base2 {
public:
    void showMessage() {
        display1();  // 通过派生类直接访问公有基类的成员函数
        //display2();  // 错误!无法直接访问私有基类的成员函数
    }
};

int main() {
    Derived derived;
    derived.showMessage();
    return 0;
}

在这个示例中,Derived 类同时继承了 Base1Base2 两个基类。Derived 类中的 showMessage() 函数可以直接调用 Base1 类的 display1() 函数,但无法直接调用 Base2 类的 display2() 函数。

输出结果为:

Base1 class

六、类模板案例

类模板允许我们定义通用的类模板,在实例化时可以指定不同的类型、常量和模板参数。

下面是一个使用类模板的示例代码,实现了一个简单的栈(Stack)类模板:

#include <iostream>
#include <vector>

template <typename T>
class Stack {
private:
    std::vector<T> elements;

public:
    void push(const T& value) {
        elements.push_back(value);
    }

    void pop() {
        if (!elements.empty()) {
            elements.pop_back();
        }
    }

    T top() const {
        if (!elements.empty()) {
            return elements.back();
        }
        throw std::out_of_range("Stack is empty.");
    }

    bool empty() const {
        return elements.empty();
    }
};

int main() {
    Stack<int> stack;
    stack.push(1);
    stack.push(2);
    stack.push(3);

    while (!stack.empty()) {
        std::cout << stack.top() << " ";
        stack.pop();
    }
    std::cout << std::endl;

    return 0;
}

在这个示例中,Stack 是一个类模板,可以使用不同类型的数据来实例化。在 main() 函数中,我们使用 Stack<int> 来创建一个整数类型的栈,并依次将元素压入栈中,然后通过 top()pop() 函数来访问和删除栈顶元素。

输出结果为

3 2 1

类模板可以实现更加灵活的泛型编程,通过指定模板参数来确定类模板中的具体类型、常量和模板参数。这使得类模板在STL(标准模板库)的容器类(如 vectorlistmap 等)中得到了广泛应用。

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tech行者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值