C++ 面向对象程序设计 - 学习笔记(持续更新中)

0、前言


1、学习笔记

1.1、头文件与类的声明

C++ 和 C 的一些比较

  • C:使用函数去处理数据,这些数据是全局的
  • C++:将数据和函数包在一起,其他类看不到;struct 和 class 等同

在这里插入图片描述


Object Based(基于对象)和 Object Oriented(面向对象)

  • Object Based:面向的是单一 class 的设计
  • Object Oriented:面向的是多个 class 的设计,class 和 class 之间的关系

Header(头文件)中的防卫式声明

不会重复引用

#ifndef __COMPLEX__
#define __COMPLEX__

...

#endif

class 的声明

template<typename T>    // 模板
class complex           // class head
{

private:
	T re, im;           // class body
}

1.1、构造函数

inline(内联)函数
内联函数是C++中一种特殊的函数,通过在函数声明前添加 inline 关键字来定义,它的主要目的是消除函数调用的开销,提高程序运行效率。

类定义内部实现的成员函数自动成为内联函数:

作用:通过在调用点展开函数体来避免函数调用的开销

特点:

  • 编译时在调用点直接展开函数代码
  • 减少函数调用的开销(压栈、跳转、返回等)
  • 适合小而频繁调用的函数

缺点

  • 代码膨胀:函数体在每个调用点展开,增加可执行文件大小
  • 不适合复杂函数:复杂函数内联会显著增加代码量
  • 不一定总是有效:编译器可能忽略inline请求

样例代码:

#include <iostream>

// 内联函数定义
inline int max(int a, int b) {
    return a > b ? a : b;
}

int main() {
    int x = 5, y = 10;
    std::cout << "Max is: " << max(x, y) << std::endl;
    // 编译时会被展开为 std::cout << "Max is: " << (x > y ? x : y) << std::endl;
    return 0;
}

在这里插入图片描述


访问级别

访问级别(Access Specifiers)是C++中控制类成员可访问性的重要机制,它定义了类成员的可见性和访问权限。

分类:

publicprivateprotect

public(共有):
特点:

  • 任何代码都可以访问

使用场景:

  • 类的接口部分
  • 需要被外部直接访问的成员
class MyClass {
public:
    int publicVar;  // 公有成员变量
    void publicFunc() { // 公有成员函数
        // 可以被任何代码访问
    }
};

private(私有):

特点:

  • 只有类自身的成员函数可以访问

使用场景:

  • 类的内部实现细节
  • 需要隐藏和保护的数据

class MyClass {
private:
    int privateVar;  // 私有成员变量
    void privateFunc() { // 私有成员函数
        // 只能被类内部的成员函数访问
    }
public:
    void accessPrivate() {
        privateVar = 10;  // 公有函数可以访问私有成员
        privateFunc();
    }
};

protect(保护):
特点:

  • 类自身和派生类可以访问
  • 类外部不可访问

使用场景:

  • 需要被派生类继承和使用的成员
  • 基类的实现细节需要暴露给派生类时
class Base {
protected:
    int protectedVar;
    void protectedFunc() {}
};

class Derived : public Base {
public:
    void accessProtected() {
        protectedVar = 20;  // 派生类可以访问基类的protected成员
        protectedFunc();
    }
};

在这里插入图片描述


构造函数

构造函数是C++中用于初始化类对象的特殊成员函数,它在对象创建时自动调用。

构造函数特点
1、函数名称和类名称相同
2、参数数量不固定(可以进行重载)
3、输入参数可以有默认值(其他函数也可以有默认值的参数)
4、没有返回值类型(void也没有)
5、初值列(可以将输入参数赋值给成员变量,其他函数没有,初始化阶段给成员变量赋值,效率更高)
6、创建对象时自动调用


样例代码

class MyClass {
public:
    // 构造函数声明
    MyClass(); 
    
    // 参数化构造函数
    MyClass(int a, double b);
};

// 构造函数定义
MyClass::MyClass() {
    // 初始化代码
}

MyClass::MyClass(int a, double b) {
    // 使用参数初始化
}

特殊的构造函数
1、拷贝构造函数
当通过已有对象创建新对象时调用

class Array {
public:
    Array(const Array& other) {
        // 深拷贝实现
        size_ = other.size_;
        data_ = new int[size_];
        std::copy(other.data_, other.data_ + size_, data_);
    }
    
private:
    int* data_;
    size_t size_;
};

2、移动构造函数
用于高效转移资源所有权

class String {
public:
    String(String&& other) noexcept 
        : data_(other.data_), size_(other.size_) {
        other.data_ = nullptr;
        other.size_ = 0;
    }
    
private:
    char* data_;
    size_t size_;
};

1.2、参数传递与返回值

1、常量成员函数
在C++中,常量成员函数(通过const关键字声明)是面向对象编程中保证对象状态安全性的重要机制。

例子

class MyClass {
public:
    void nonConstFunc();    // 非常量成员函数
    void constFunc() const; // 常量成员函数
};

若成员变量声明为mutable,则常量成员函数可以修改其值:


2、参数传递

在这里插入图片描述

传递引用就像传递指针一样快

  1. 传值 (By Value)
  • 行为:函数获得参数的独立副本,修改不影响调用方的原始数据。
  • 性能:适合小型数据(如intdouble、指针),但对于大型对象(如std::vector)会产生拷贝开销。
void increment(int x) { x++; } // 修改的是副本
int a = 10;
increment(a); // a仍为10
  1. 传引用(By reference)
  • 行为:直接操作原始数据,函数内修改会影响调用方。
    用途:
  • 输出参数:通过引用返回多个结果。
    避免拷贝:传递大型对象(如std::string、容器)。
void increment(int& x) { x++; } // 修改原值
int a = 10;
increment(a); // a变为11
  1. 传常引用(to const)
  • 行为:提供对原始数据的只读访问,禁止修改,同时避免拷贝。
  • 优势:兼容常量对象(如const int&可接受字面量5)。
void print(const std::string& s) { 
    std::cout << s; // 只读访问,安全高效
}
print("Hello"); // 合法:隐式构造临时std::string

尽量返回值为引用
什么情况返回值不能使用引用?
对象是在函数内创建的


1.3、friends(友元)

在C++中,友元(Friend) 是一种打破类封装性的特殊机制,允许其他类或函数访问当前类的私有(private)和保护(protected)成员。

特点:

  • 相同 class 的各个 object 互为 friends(友元)
  • 在类内部声明友元关系,允许外部函数或类访问私有/保护成员:
  • 友元函数或类可以直接访问当前类的所有成员(包括私有和保护成员),无视访问修饰符。
  • 单向性:友元关系不可传递、不可继承、不可双向自动授予:
    若A是B的友元,B不自动成为A的友元。
    若A是B的友元,C继承A,则C不是B的友元。

例子:

class Point {
    int x, y;
public:
    Point(int x, int y) : x(x), y(y) {}

    // 声明友元运算符
    friend std::ostream& operator<<(std::ostream& os, const Point& p);
};

std::ostream& operator<<(std::ostream& os, const Point& p) {
    os << "(" << p.x << ", " << p.y << ")"; // 直接访问私有成员
    return os;
}

2、常见问题

2.1、xx

【问题描述】


【问题原因】


【解决方法】


3、常用颜色

紫色
红色
蓝色
绿色
橙色

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值