c++ 基础 笔记

2024-01-09 04:26:23

1?外部访问就是 实例类后 访问类中变量

class MyClass {
public:
    int publicVar; // 公有变量
protected:
    int protectedVar; // 受保护变量
private:
    int privateVar; // 私有变量
};

MyClass obj;
obj.publicVar = 1; // 正确: 公有变量可以在类外部直接访问
obj.protectedVar = 2; // 错误: 受保护变量不能在类外部直接访问
obj.privateVar = 3; // 错误: 私有变量不能在类外部直接访问

2 基类protected成员是子类的内部成员

class Base {
private:
    int privateVar; // Base类私有成员
protected:
    int protectedVar; // Base类受保护成员
};

class Derived : public Base {
public:
    void AccessMembers() {
        // privateVar = 1; // 错误: Derived类不能访问Base类的私有成员
        protectedVar = 2; // 正确: Derived类可以访问Base类的受保护成员
    }
};

int main() {
    Derived obj;
    // obj.privateVar = 1; // 错误: 不能在类外部访问私有成员
    // obj.protectedVar = 2; // 错误: 不能在类外部访问受保护成员
}

3 创建指针 指向对象用 -> ; 实例化对象用 .

3.1 用 -> 的堆 ( -> 不能用在栈上)

ThrLevel1* thrLevel1 = new ThrLevel1(this, ok); // 创建 指针型用 -> 
connect(thrLevel1, &ThrLevel1::signal, this, &qt_ok::signalThrLevel1);
// 启动线程
thrLevel1->setInstId("BTC-USDT");
thrLevel1->start();

3.2 用 . 的栈

ThrLevel1 thrLevel1(this, ok);
thrLevel1.setInstId("BTC-USDT"); // 使用点操作符访问对象的成员函数
thrLevel1.start();

4?名称遮蔽? 加类型名称 声明变量 是局部变量 把类全局变量搞成了 变量所在的局部变量

class MyClass {
public:
    MyClass() {
        MyType* myVar = new MyType(); // 这里创建了一个局部变量 myVar
        // ...
    }

    ~MyClass() {
        delete myVar; // 这里尝试删除的是成员变量 myVar,但它实际上从未被赋值
    }

private:
    MyType* myVar; // 这是类的成员变量
};

如果?myVar 定义的是类的成员变量 但是在构造函数中? 加类型名称 声明变量 导致成了局部变量

MyType* myVar = new MyType();

5 取址和引用(别名)要区分

 Okex2* p = &ok;   // p 是指向 Okex2 类型对象的指针,现在 p 存储了 ok 的地址
 Okex2& ref = ok; // ref 是 ok 对象的引用 

6 多个类传递使用只声明一次 ok, 传递指针 定义指针型成员 thrLevel1->okInstance = &ok;

// 1 声明
ok()

// 2 设置方法 让别的类可以外部 取到 ok的内存地址 取指
Ok* qt_ok::getOk() 
{
    return &ok; 
}

// 3 别的类要 声明指针变量 之后ok对象的地址赋值给 此变量
// ThrBase.h

#include "Ok.h"
class ThrBase : public QThread {
    Q_OBJECT

public:
    ThrBase(QObject* parent);
    ~ThrBase();

    void setOkInstance(Ok* ok);
 
protected: // 与子类共享的内部变量
    Ok* okInstance; // 存储Okex2实例的指针
// ThrBase.cpp
#include "ThrBase.h"

ThrBase::ThrBase(QObject* parent) : okInstance(nullptr))
{
}

ThrBase::~ThrBase()
{
}

void ThrBase::setOkInstance(Ok* ok)
{
	okInstance = ok;
}
//4 传值
thrLevel1 = new ThrLevel1(this); // 创建 指针型用 -> 
thrLevel1->setOkInstance(this->getOk());

不用 get set 封装

ok();

thrLevel1->setOkInstance(&ok);

不用封装 setOkInstance方法 直接赋值

okInstance成员变量改为public

thrLevel1->okInstance = &ok;

7 成员变量?局部变量

private: //?成员变量

? ? std::string host;

void re(){

? std::string x ; // 局部变量

}

8 类的静态成员(全局成员)和非静态成员

class Car {
public:
    int year; // 非静态成员变量
    static int numberOfCars; // 静态成员变量

    Car() { // 构造函数
        numberOfCars++; // 每创建一个Car对象,静态成员变量numberOfCars就增加1
    }
};

int Car::numberOfCars = 0; // 初始化静态成员变量
+--------------------------+
|         代码区           |
| 存放CPU执行的机器指令代码 |
+--------------------------+
|       常量存储区         |
| 存放常量字符串和其他常量 |
+--------------------------+
| 全局/静态存储区 (BSS段)  |
| 未初始化的全局变量和静态变量 |
+--------------------------+
| 全局/静态存储区 (数据段)  |
| 已初始化的全局变量和静态变量 |
+--------------------------+
|          堆区            |
| 通过new分配的内存         |
+--------------------------+
|          栈区            |
| 函数调用时的局部变量和参数 |
+--------------------------+
// 创建对象 就分配在栈区  new就在堆区

     基类 ThrBase
+---------------------+
| vptr                | ----> 指向 ThrDerived1 的 vtable 纯虚函数表
+---------------------+      (如果 ThrDerived1 中有新的虚函数或覆盖了基类的虚函数,则包含这些函数的指针)
| ... 基类成员 ...    |
+---------------------+

派生类 ThrDerived1 的对象内存布局:
+---------------------------------+
|        ThrBase 部分             |
+---------------------------------+
| ThrBase 的非静态数据成员        |
+---------------------------------+
| ThrBase 的虚函数表指针(vptr)    | ----> 指向 ThrDerived1 的虚函数表
+---------------------------------+
|        ThrDerived1 部分         |
+---------------------------------+
| ThrDerived1 的非静态数据成员    |
+---------------------------------+
| ThrDerived1 重写的虚函数        |
+---------------------------------+
| ThrDerived1 特有的虚函数        |
+---------------------------------+
| ThrDerived1 特有的非虚函数      |
+---------------------------------+

9 继承基类后的多态(区别类的多态) 后 使用 基类指针 用基类 有新功能

class Base {
public:
    virtual void doSomething() = 0; // 纯虚函数
    virtual ~Base() {} // 虚析构函数以确保正确的析构派生类
};

class Derived : public Base {
public:
    void doSomething() override { // 必须实现基类的纯虚函数
        // ... 实现细节 ...
    }
};
// 多态 
ThrBase* base1 = new ThrDerived1(); 只能访问基类部分 run已经被改写所以不是纯虚函数

// 继承后的派生类 
ThrDerived1* base1 = new ThrDerived1();  可以访问所有部分

多态性主要指的是能够通过基类的接口(指针或引用)来操作派生类对象,并在运行时根据对象的实际类型调用相应的重写函数。当使用派生类类型的指针时,你直接调用的是那个派生类的成员函数,这是静态绑定。多态性涉及到动态绑定,即在运行时才确定调用哪个具体的函数。

10 python的 @classmethod 与 c++静态static

// .h
class Db {
public:
    // ... 其他成员 ...
    static bool createTableWithAttrsPlus(Db& db, const std::string& table_name, const std::vector<std::string>& attrs);
    // ... 其他成员 ...
};

// .cpp
bool Db::createTableWithAttrsPlus(Db& db, const std::string& table_name, const std::vector<std::string>& attrs) {
    // ... 实现创建表的逻辑 ...
}

// 使用
std::vector<std::string> attrs = { /* 属性列表 */ };
bool success = Db::createTableWithAttrsPlus(dbInstance, "table_name", attrs);

静态函数本身不占用调用者的堆栈或堆空间,因为它们属于类,而不是类的某个实例

区别与先实例化或先创建对象指针

// 如果是对象实例
Db db;
db.getDatabaseConnection();

// 如果是对象指针
Db* db = new Db();
db->getDatabaseConnection();
+------------------+
|     代码区       |
| (存放程序的指令) |
+------------------+
|     常量区       |
| (存放常量数据)   |
+------------------+
|  全局/静态存储区  |
| (全局变量和静态变量)|
+------------------+
|        堆        |
| (动态分配的内存)  |
+------------------+
|        栈        |
| (函数调用和局部变量)|
+------------------+

代码区:存放CPU执行的机器指令。

常量区:存放字符串常量和其他常量数据。这部分内存只读。

全局/静态存储区:存放全局变量和静态变量。在程序(进程)的生命周期内一直存在。

堆:由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。

栈:由操作系统自动分配释放,存放函数的参数值、局部变量等。其操作类似于数据结构中的栈。

11 静态变量?

静态成员变量在类的所有实例之间共享,它们不属于任何单个对象实例,而是属于类本身。在C++中,这意味着无论创建了多少个对象,静态成员变量只有一份拷贝。

任何能够访问该静态成员变量的代码都可以对其进行读写(除非它被声明为const(只读)),无论这个代码位于哪个对象中。

#include <iostream>
#include <vector>

class MyClass {
public:
    static std::vector<int> shared_data; // 静态成员变量

    void addValue(int val) {
        shared_data.push_back(val); // 向静态成员变量中添加数据
    }

    void printValues() {
        for (int val : shared_data) {
            std::cout << val << " ";
        }
        std::cout << "\n";
    }
};

// 在类外初始化静态成员变量
std::vector<int> MyClass::shared_data;

int main() {
    MyClass obj1;
    MyClass obj2;

    obj1.addValue(1); // obj1 添加值到 shared_data
    obj2.addValue(2); // obj2 也添加值到同一个 shared_data

    // 两个对象打印出相同的静态成员变量
    obj1.printValues(); // 输出: 1 2
    obj2.printValues(); // 输出: 1 2

    return 0;
}

文章来源:https://blog.csdn.net/tenc1239/article/details/135391276
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。