一、C++面向对象-封装(Encapsulation)

C++数据域封装 Data Field Encapsulation (数据域封装)class Circle { //数据域采用public的形式有两个问题 public: //First,data may be tampered (数据会被类外的方法篡改) double radius; //Second,it makes the clas 阅读详情

类

定义:
类用于指定对象的形式,它包含了数据和用于处理数据的方法,可以把类当作自定义的数据类型
![image](assets/image-20230908091828-66lyqb2.png)
访问权限:
默认访问权限private

**public**公有权限:一个类的public成员变量、成员函数,可以通过类的成员函数、类的实例变量进行访问

**protected**保护权限:一个类的protected成员变量、成员函数,无法通过类的实例变量进行访问;可以通过公有函数接口与友元函数、友元类进行访问

**private**私有权限:一个类的private成员变量、成员函数,无法通过类的实例变量进行直接访问;可以通过公有函数接口与友元函数、友元类进行访问

对象

定义:
实例化一个事物,称为某个具体事物的一个个体,创建对象后才会分配具体内存空间
创建方式:
静态创建

动态创建
class Human
{
public:
private:
	string name;
	int age;
};

Human person; //静态创建
Human *person1 = new Human; //动态创建

访问属性及方法

针对静态创建的对象

<对象名>.<属性或方法>
Human person; //静态创建
person.name;
person.age;

针对动态创建的对象

<对象指针名>-><属性或方法>
Human *person1 = new Human; 
person1->name;
person1->age;

构造函数

功能:
在构造对象时自动调用此函数,用户自定义的构造函数往往使用初始化对象内的成员变量
使用:
函数名与类名一致没有返回值

默认构造函数:

只有四种情况下,类中才会生产默认构造函数:

	1.成员变量中存在带有默认构造函数的类对象

	2.继承自带有默认构造函数的基类

	3.该类中具有虚函数

	4.继承自一个或多个虚基类

当使用无参构造函数静态创建一个对象的时候,不能添加小括号(),编译器默认此为函数声明
class Circle
{
public:
    Circle();
private:
    int x;
    int y;
    int r;
};

Circle::Circle()
{
    cout << "default constructor" << endl;
}


无参构造函数

调用的时候,不要加()

//定义
Person::Person()
{
    isFemale = true;
    height = 165;
    name = "XH";
    age = 18;
}

//调用
//普通变量
Person p1;
//指针变量
Person *pa = new Person();
pa->show();

构造函数的重载:

调用的时候保证有相对的重载函数

#include <iostream>

using namespace std;

class Circle
{
public:
    Circle();
    Circle(int _x, int _y, int _r);
private:
    int x;
    int y;
    int r;
};

Circle::Circle()
{
    cout << "default constructor" << endl;
}

Circle::Circle(int _x, int _y, int _r)
{
    x = _x;
    y = _y;
    r = _r;
    cout << "Full constructor" << endl;
}

初始化列表:

在初始化时,也可以使用初始化列表的方式来实现构造函数,一般用在继承中

一般是全部成员都要初始化,除非初始化有问题的

先执行初始化列表,再之下函数体
class Circle
{
public:
    Circle();
    Circle(int _x, int _y, int _r);
private:
    int x;
    int y;
    int r;
};

Circle::Circle()
{
    cout << "default constructor" << endl;
}

//初始化列表
Circle::Circle(int _x, int _y, int _r) : x(_x), y(_y), r(_r)
{
    cout << "Full constructor" << endl;
}

委托构造函数:

功能:
委托构造函数允许在同一个类中一个构造函数调用另外一个构造函数,可以在变量初始化时简化操作
使用:
一般是参数少的委托参数多的

委托构造函数:让别人干活

目标构造函数:干活的
注意点:
不要出现委托环
class Circle
{
public:
    Circle();
    Circle(int _x);
    Circle(int _x, int _y, int _r);
private:
    int x;
    int y;
    int r;
};

Circle::Circle()
{
    cout << "default constructor" << endl;
}

//委托构造函数:让别人干活
Circle::Circle(int _x) : Circle(_x, 0, 0)
{
    ;
}

//目标构造函数:干活的
Circle::Circle(int _x, int _y, int _r) : x(_x), y(_y), r(_r)
{
    cout << "Full constructor" << endl;
}

拷贝构造函数:

功能:
当一个对象需要通过另一个对象初始化,则需要使用拷贝构造函数
语法:
类名(const 类名 &other)
{
}
调用拷贝构造函数时机:
1、主动创建对象时,用一个对象去初始化另一个对象的时候

2、一个对象以**值传递**的形式传入函数体

3、一个对象以**值的形式**从函数返回
注意事项
1、译器默认生成的拷贝构造函数为浅拷贝(但是实际上,并不是一定会生成默认的拷贝构造函数)
	1、成员变量中存在带有拷贝构造函数的类对象
	2、继承自带有拷贝构造函数的基类
	3、该类中存在虚函数
	4、继承自一个或者多个虚基类
2、如果实现了拷贝构造函数,那么编译器不会生成默认构造函数,反之如果实现了默认构造函数,那么编译器还是会生成一个默认拷贝构造函数
3、const关键字可以省略,但是引用&不能省略,原因在于如果省略,那么形参接受值传递时发生拷贝构造,导致死循环
4、关于指针,因此除非与new一起使用,否则将不会调用任何构造函数
class Pointer
{
public:
    Pointer();
    Pointer(int _x, int _y = 100);
    Pointer(const Pointer &other);
    void show();
private:
    int x;
    int y;
};

// 复制构造函数,用于创建与现有Pointer对象相同的新的Pointer对象
// 参数 other: 一个现有的Pointer对象,从该对象复制x和y成员变量的值
Pointer::Pointer(const Pointer &other) : x(other.x) , y(other.y)
{
}

2、一个对象以 值 传递的形式传入函数体
void show(Pointer p)
{
}

3、一个对象以 值的形式 从函数返回
Pointer show_1()
{
	Pointer p;
	return p;
}

Pointer p;

1、主动创建对象时,用一个对象去初始化另一个对象的时候
//调用 拷贝构造函数
Pointer p1(p); //隐式调用 拷贝构造函数
Pointer p2 = p; //显示调用 拷贝构造函数

//不加编译选项是 全参构造(编译器优化)
//加上-fno-elide-constructors 会显示调用拷贝构造函数
/*
 * 10 : Pointer temp(10) --> Full construct
 * p3 = temp --> copy construct
 * temp --> 释放
 */
Pointer p3 = 10;
		



深拷贝和浅拷贝
浅拷贝:
默认拷贝构造函数为浅拷贝

浅拷贝对指针类型变量,仅拷贝对应内存地址,不会开辟新内存空间
深拷贝:
认为重载构造函数,新开辟一段内存空间
//浅拷贝
/*
Circle::Circle(const Circle &other) : x(other.x), y(other.y), r(other.y)
{
    cout << "Copy constructor" << endl;
}
*/

//深拷贝
Circle::Circle(const Circle &other) : x(other.x), y(other.y), r(other.y)
{
    p = new int(*(other.p));

    cout << "Copy constructor" << endl;
}

隐式拷贝构造函数:
1、一个对象作为函数参数,以值传递的方式传入函数体

2、一个对象作为函数返回值,以值传递的方式从函数返回

3、以A a = b的方式构造a,其中b也是A类型

移动构造函数:

功能:
所谓移动语义,指的就是以移动而非深拷贝的方式初始化含有指针成员的类对象。简单的理解,移动语义指的就是将其他对象(通常是临时对象)拥有的内存资源“移为已用”
语法:
类名(类名 &&other)
{
}
和拷贝构造函数的区别:

拷贝构造:
在这里插入图片描述

移动构造:

在这里插入图片描述

触发移动构造函数的时机:
如果临时对象即将消亡,并且它里面的资源是需要被再利用的,这个时候我们就可以触发移动构造。
Circle::Circle(Circle &&other) : x(other.x), y(other.y), r(other.y), p(other.p)
{
    other.p = nullptr;

    cout << "Move constructor" << endl;
}

std::move函数
可以以非常简单的方式将左值转换为右值引用。通过std::move,可以避免不必要的拷贝操作。std::move是为性能而生。
noexcept
用于指示函数是否可能抛出异常。在函数声明或定义时使用noexcept关键字可以提供编译器和程序员有关函数异常行为的信息,从而更好地管理异常处理和优化代码

使用场景

1、	在函数中使用
void myFunction() noexcept 
{
    // 函数实现
}
2、在表达式中使用
bool isSafe = noexcept(myFunction());

注意事项
1、如果函数声明为noexcept,而实际上在函数体中抛出了异常,C++标准要求调用 std::terminate 函数,导致程序终止。
2、noexcept可以用于优化,编译器可能会在知道函数不会抛出异常时进行一些优化
3、noexcept函数可以安全地调用可能会抛出异常的函数,而不必担心在异常发生时程序终止。
4、在异常安全的代码编写中,noexcept可以帮助确定何时调用可能会抛出异常的函数,以便正确处理异常

构造函数调用规则

拷贝构造函数的隐式调用

移动构造与拷贝构造的调用规则:

	有移动调用移动

	没有移动调用拷贝

	没有拷贝直接报错

析构函数

功能:
对象释放的时候自动调用

释放对象内申请的资源,包括堆区的内存,线程,进程,文件描述符
定义:
与类名相同,在前面加位取反符~。且不能有任何参数与返回值
特点:
1、没有参数没有返回值,但有this指针
2、析构函数不能用const修饰
3、一个类有且只有一个析构函数,所以肯定不能重载
4、如果不手动销毁对象指针,程序运行结束时,编译器将不会进行处理,操作系统会直接进行内存回收,因此不会调用析构函数

this指针

功能:
用于保存对象的地址,每一个非静态函数中都有一个隐藏参数this
用法:
1、在非静态函数中,传入参数名与对象内成员变量相同时区分两个变量

2、在非静态函数中,需要返回对象
#include <iostream>

using namespace std;

class Person
{
public:
    Person();
    Person(int age, int height);
    Person(const Person &other);
    ~Person();

    void show();
    Person setInfo(int age, int height);
private:
    int age;
    int height;
};

Person::Person() : age(0), height(0)
{
    cout << "empty constructor" << endl;
}

Person::Person(int age, int height)
{
    this->age = age;
    this->height = height;
    cout << "Full constructor" << endl;
}

Person::Person(const Person &other) : age(other.age), height(other.height)
{
    cout << "Copy constructor" << endl;
}

Person::~Person()
{
    cout << "destructor" << endl;
}

void Person::show()
{
    cout << "age : " << age << endl <<
        "height : " << height << endl;
}

Person Person::setInfo(int age, int height)
{
    this->age = age;
    this->height = height;

    return *this;
}

int main(int argc, const char *argv[])
{
    Person p1(18, 180);
    p1.show();
    p1.setInfo(20, 185).setInfo(22, 170);
    p1.show();

	return 0;
}

static

静态成员变量:
语法:
在类中**声明:**
static <类型修饰符><变量名>
在类外**初始化:**
<类型修饰符><类名>::<变量名> = <初始化值>
特点:
静态成员初始化,必须放在类外

static静态成员变量时所有**对象共享的**,并在对象创建之前就已经产生

static修饰的成员变量**属于类不属于具体的对象**

static成员变量的内存在程序开始运行时分配,程序运行结束时释放内存

**静态成员使用前必须初始化**,否则会在linker(链接)步骤出错

在成员函数中可以正常访问静态成员变量

对于公有静态成员变量,可以不需要构造对象直接访问,对于私有静态成员变量则不行
静态成员函数:
语法:
static <函数返回值><函数名>(参数列表)
特点:
1、静态成员函数**没有thie指针**,**与类相关**,不与对象关联,在调用静态函数时,可以在没有对象时调用

2、不能访问非静态成员,**只能访问静态成员**

3、可以被对象直接使用

4、可以通过类名直接访问
#include <iostream>

using namespace std;

class Pointer
{
public:
    Pointer();
    Pointer(int _x);

    void show();
    void setY(int _y);
    static void setNoStaticX();
    static void showInfo();
    int x;
    static int z;
private:
    static int y;//类内定义
};

//静态成员变量,在类中声明
//类外初始化
int Pointer::y = 100;
int Pointer::z = 10;

Pointer::Pointer() : x(0)
{
    cout << "empty constructor" << endl;
}

Pointer::Pointer(int _x) : x(_x)
{
    cout << "full constructor" << endl;
}

void Pointer::show()
{
    cout << "x : " << x << endl; 
    cout << "y : " << y << endl; 
    //静态成员函数,没有this指针,无法调用普通的非静态成员函数
    //普通的非静态成员函数,拥有this指针,可以调用静态成员函数
    this->setNoStaticX();
}

void Pointer::setY(int _y)
{
    y = _y;
}

void Pointer::setNoStaticX()
{
    //在静态成员函数中,不可以读写非静态成员变量
    //可以读写静态成员变量
    y = 300;
}

void Pointer::showInfo()
{
    //静态成员函数中,可以调用其他静态成员函数
    cout << "showInfo y : " << y << endl;
    setNoStaticX();
}

int main(int argc, const char *argv[])
{
    Pointer o1(1);
    o1.show();
  
    cout << "------------" << endl;
    Pointer o2;
    o2.setY(50);
    cout << "o1 : ";
    o1.show();
    cout << "o2 : ";
    o2.show();
    cout << "------------" << endl;
    o1.setNoStaticX();
    o1.show();
    Pointer::showInfo();
    o1.show();
    cout << "------------" << endl;
    //通过类名可以直接访问静态成员变量
    //同事也需要静态成员变量被public修饰
    cout << "z : " << Pointer::z << endl;
    cout << "------------" << endl;
    //静态成员函数可以通过类名直接使用
    //必须要在public权限下
    Pointer::setNoStaticX();

	return 0;
}

const

const成员变量
const成员变量**只能在初始化列表中初始化**
const成员函数 —核心:const修饰的是this指针
1、防止成员函数修改非静态成员变量的值,但可以修改静态成员变量(仍然可以访问所有成员变量的值)

2、const成员函数只能调用const成员函数,非const成员函数既能调用非const成员函数,也能调用const成员函数

3、const成员函数也可以与同名非const成员函数构成函数重载(本质修饰的时this指针,因此重载方式为类型不同)
#include <iostream>

using namespace std;

class Pointer
{
public:
    Pointer(int _x, int _y);
  
    //const修饰的是this指针
    void show() const;
    //被cosnt修饰的成员函数,可以发生重载
    //重载的类型为参数类型不同
    void show();
private:
    int x;
    const int y;
    static int z;
};

int Pointer::z = 0;

Pointer::Pointer(int _x, int _y) : x(_x), y(_y)
{
    cout << "full consturctor" << endl;
}

void Pointer::show() const
{
    cout << "const show() : " << endl; 
    //对于非静态成员变量,不可以修改值,但是可以读取值
    //对于非静态成员而言,读取和修改值都可以
    z = 100;
    cout << "x : " << x <<  " y : " << y << " z : " << z << endl;
}

//与const成员函数发生重载
//对于外部对象而言
//非const对象,调用非const成员函数
//const对象,调用const成员函数
void Pointer::show()
{
    cout << "show() : " << endl;
    cout << "x : " << x << " y : " << y << " z : " << z << endl;
}

int main(int argc, const char *argv[])
{
    //对于非const对象而言,可以调用非const成员函数
    //也可以调用const成员函数
    Pointer p(10, 20);
    p.show();

    //针对于const对象而言,不能调用非const成员函数
    const Pointer p2(20, 30);
    p2.show();

	return 0;
}

static和const之间调用关系

static成员变量属于整个类(因此在创建对象前就产生了,也必须初始化,不然链接阶段会报错),程序结束时释放内存,成员数据变量可以访问静态成员变量。公有静态数据成员可以直接访问,但私有静态成员变量不行

静态成员函数只能访问静态成员数据,无this指针,属于类而不属于某个对象,可以通过类名直接访问,在无对象时可以调用

const成员数据只能通过初始化列表进行初始化

static const修饰的成员函数只能修改s的值,const成员函数只能调用const成员函数。当const成员函数与同名非const成员函数会发生重载,const对象会调用const成员函数,非const对象调用非const成员函数(如果没有发送重载的话,普通对象就可以直接调用const或者普通成员函数)(本质上修饰的是this指针,属于参数类型不同)this实际上是成员函数的一个形参,在调用成员函数时将对象的地址作为实参传递给this。不过this这个形参是隐式的,它并不出现在代码中,而是在编译阶段由编译器默默将它添加到参数列表中。这个额外的参数,实际上就是this,它是成员函数和成员变量之间的桥梁。故const成员变量不能访问非const成员函数

const修饰的成员函数:实际上修饰的是this指针指向空间的内容不可被修改,有了const修饰的成员函数,其this指针类型:const Date const* (左定值,右定向)而普通的成员函数:可以修改成员变量 ,其this指针类型:Date const*

成员类型访问非静态成员变量访问静态成员变量调用非const函数调用const函数
非static
非const
✔️✔️✔️✔️
非static
const
❌(除非 mutable)✔️❌✔️
static
非const
❌✔️❌(无 this)✔️(可调用静态函数)
static
const
❌✔️❌✔️

友元函数

概念:
友元函数不是成员函数,它**定义在类的外部**,只需要在**类中声明**即可

友元函数可以访问所有私有成员和保护成员,一般情况下不适用,使用不当会破坏程序面向对象的特性
语法:
//friend <函数声明>

#include <iostream>

using namespace std;

class Box
{
public:
    Box();
    Box(int _w);
    //声明友元函数
    friend void printfBoxWidth(const Box box);
private:
    int width;
};

Box::Box()
{
    width = 0;
    cout << "empty constructor" << endl;
}

Box::Box(int _w) : width(_w)
{
    cout << "full constructor" << endl;
}

//友元函数的定义
//外部函数,能访问对象私有成员 
void printfBoxWidth(Box box)
{
    cout << "box width is " << box.width << endl;
}

int main(int argc, const char *argv[])
{
    Box b;
    printfBoxWidth(b);
    Box b1(10);
    printfBoxWidth(b1);

	return 0;
}

友元类

概念:
**一个类中声明另一个类是自己的友元**

假如类A声明类B是自己的友元,那么在类B中可以访问类A所有的私有成员和保护成员
语法:
friend <类名>
注意事项:
1、友元不具有相互性,若类B是类A的友元,类A不一定是类B的友元

2、友元**不能被继承**(你爹的朋友不一定是你的朋友)

3、友元**不具有传递性**(你朋友的朋友不一定是你的朋友)
#include <iostream>

using namespace std;

class FriendTest;

class Box
{
//友元类
friend class FriendTest;
public:
    Box();
    Box(int _w);

    void show();
private:
    int width;
};

class FriendTest
{
public:
    void setBox(Box &b, int _w);
private:
};

Box::Box()
{
    width = 0;
    cout << "empty constructor" << endl;
}

Box::Box(int _w) : width(_w)
{
    cout << "full constructor" << endl;
}

void Box::show()
{
    cout << "width : " << width << endl;
}

void FriendTest::setBox(Box &b, int _w)
{
    b.width = _w;
}

int main(int argc, const char *argv[])
{
    Box b;
    Box b1(10);
    b1.show();

    FriendTest fb1;
    fb1.setBox(b1, 20);
    b1.show();

	return 0;
}

内联函数

目的:
引入内联函数的目的是为了解决程序中函数**调用的效率**问题
原理:
内联函数在编译器阶段是直接复制 **“镶嵌”到主函数**中去的,就是将内联函数的代码直接放在内联函数的位置上,这与一般函数不同,主函数在调用一般函数的时候,是指令跳转到被调用函数的入口地址,执行完被调用函数后,指令再跳转回主函数上继续执行后面的代码;而由于内联函数是将函数的代码直接放在了函数的位置上,所以没有指令跳转,指令按顺序执行
语法:
**函数声明和定义必须在同一文件**进行,**声明与定义时需要添加inline**修饰符

内联函数内**不允许**使用<u>循环语句与开关语句</u>

内联函数不能超过10行,如果超过则编译器不会替换,而还是使用调用的方式调用函数
inline <返回值> <函数名>(<形参表>) {<函数体>}
类与内联函数:
1、类内定义的函数都是内联函数,不管是否有inline修饰符

2、声明在类外,定义在类外,看是否有inline修饰符
内联函数与宏定义的区别:
1、宏是由预处理器处理进行代码替换,而内联函数有编译器进行代码替换

2、内联函数时真正的函数

运算符重载

简介:
C++语言预定的运算符只能操作基础数据类型,对于用户自定义的类型,在进行运算时也需要类似的操作

运算符重载实际上是对运算符赋予新的运算方式
目的:
使对象的运算操作更加简洁明了
规则:

大部分运算符可以重载,少部分不行
在这里插入图片描述
在这里插入图片描述

重载运算符可以对运算符号做出新的解释,但基本语义不变

1、无法改变运算符优先级
2、无法改变运算符结构性
3、无法改变运算符所需要的操作数
4、无法创建新的运算符
语法:

类的成员函数

<函数返回值> operator <运算符> (<形参表>)
{  
           <函数体>                                                
}

类的友元函数

friend <函数返回值> operator <运算符> (<形参表>)
{  
           <函数体>                                                
}
#ifndef _overload_HPP
#define _overload_HPP

#include <iostream>

class OverLoad
{
public:
    OverLoad();//无参构造
    OverLoad(int _x, int _y);//全参构造
    OverLoad(const  OverLoad &other);//拷贝构造
    OverLoad(OverLoad &&other);//移动构造
    ~OverLoad();

    const OverLoad operator+(const OverLoad &other) const;
    OverLoad &operator=(const OverLoad &other);
    bool operator==(const OverLoad &other) const;

    void show();
private:
    int x;
    int y;
};

#endif

#include "overload.hpp"
using namespace std;


OverLoad::OverLoad() : x(0), y(0)
{
    cout << "empty constructor" << endl;
}

OverLoad::OverLoad(int _x, int _y) :
    x(_x), y(_y)
{
    cout << "full constructor" << endl;
}

OverLoad::OverLoad(const OverLoad &other) :
    x(other.x), y(other.y)
{
    cout << "copy constructor" << endl;
}

OverLoad::OverLoad(OverLoad &&other) :
    x(other.x), y(other.y)
{
    cout << "move constructor" << endl;
}

OverLoad::~OverLoad()
{
}


const OverLoad OverLoad::operator+(const OverLoad &other) const
{
    OverLoad temp;
    temp.x = this->x + other.x;
    temp.y = this->y + other.y;

    return temp;
}

OverLoad &OverLoad::operator=(const OverLoad &other)
{
    this->x = other.x;
    this->y = other.y;

    return *this;
}
bool OverLoad::operator==(const OverLoad &other) const
{
    if((this->x == other.x) && (this->y == other.y))
        return true;
    return false;
}

void OverLoad::show()
{
    cout << "x : " << x << endl;
    cout << "y : " << y << endl;
}

#include <iostream>
#include "overload.hpp"
using namespace std;


int main(int argc, const char *argv[])
{
    OverLoad o1(10, 20);
    cout << "o1 : ";
    o1.show();

    OverLoad o2 = (o1 + o1);
    cout << "o2 : ";
    o2.show();

    OverLoad o3 = o2;
    cout << "o3 : ";
    o3.show();
    cout << "o2 : ";
    o3.show();
  
    if(o3 == o1)
    {
        cout << "true" << endl;
    }
    else
    {
        cout << "false" << endl;
    }

	return 0;
}

N5105 PVE UEFI核显直通Windows:从黑屏到HDMI输出的实战调优 本文详细介绍了在N5105处理器上实现PVE UEFI核显直通Windows的实战调优方法。针对黑屏和HDMI音频无法识别等常见问题,提供了系统参数调整、驱动模块加载、虚拟机配置等解决方案,帮助用户成功实现核显直通并优化性能。 阅读详情

相关推荐

SBM与超效率SBM模型实战:从原始面板数据到MATLAB高效实现

本文详细介绍了SBM模型与超效率SBM模型的核心原理,并提供了从原始面板数据预处理到MATLAB高效实现的完整实战指南。通过具体代码解析,帮助研究者掌握如何利用MATLAB进行数据标准化、模型构建、效率求解及结果可视化,从而精准评估决策单元的相对效率,尤其适用于在高效单元中进一步精细排名的场景。

weixin_29100399的博客 478

C++ Encapsulation(封装)

OOP的主要有三个主要的特点。 一个

a130737的专栏 2968

常见卫星图源下载教程

上面列出的8个常见的亚米级别数据源都可以通过xyz协议或者wmts/wms协议进行下载。这些协议是什么?地理信息数据为了方便网络传输,制定了一系列的地理数据传输标准(wms/wmts/xyz等)。协议特点优点缺点栅格数据支持矢量数据支持WMS通过HTTP请求获取GIS数据,服务器会将数据渲染成图像高度定制的地图;交互性强服务器渲染图像,响应时间较长支持有限支持WMTS提供预渲染的地图瓦片速度快,因为地图瓦片可以预先生成并在请求时快速提供瓦片的内容是预先确定的,无法进行定制支持。

锐多宝的地理空间 1万+

Hello C++(三)——封装(Encapsulation)

一、封装简介 C语言等面向过程编程中,数据以及数据的相关操作函数都是分离的独立个体;在C++等面向对象编程中,数据以及数据的相关操作被设计为对象,对象包括属性(数据)和操作(函数),两者共同构成对象实体(即类实体)。面向对象编程使程序更模块化,更易读易写,提升了代码重用到一个更高的层次。 面向对象编程中,数据和数据的操作封装为了对象。封装可以隐藏实现细节,使得代码模块化,是把过程和数据包围起来,对数据的访问只能通过已定义的接口。 封装是一种对外提供服务的模型,封装模型是对世间万物的个体抽象。 封装的

天山老妖 1486

【Bug已解决】openclaw max turns reached / Tool calls exceeded limit — OpenClaw 最大轮次超限解决方案

OpenClaw 在执行过程中达到最大轮次限制任务未完成,本质是 --max-turns 设置过小或任务过于复杂。文中给出增加轮次、--continue 继续、分步执行等完整方案。

一键难忘的博客 5505

【零基础入门unity游戏开发——2D篇】SpriteEditor图片编辑器

【零基础入门unity游戏开发——2D篇】SpriteEditor图片编辑器

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2330

java 面向对象编程之二

面向对象程式设计方法中,封装(英语:Encapsulation)是指,一种将抽象性函式接口的实作细节部份包装、隐藏起来的方法。 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。 要访问该类的代码和数据,必须通过严格的接口控制。 封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。 适当的封装可以让程式码更容易理解

523

统信UOS丨开机无法进入系统 无法打开控制台访问权限,root账号被锁定(cannot open access to console, the root account is locked)

步骤四:分别打开文件发现Roota下的fstab就是我们要找的文件,打开查看Roota的属性发现其为挂载的磁盘nvme0n1p3。步骤三:按Win+E打开文件管理器在分区中查找/etc/fstab文件,发现Roota和Rootb下都有该文件。步骤二:按键盘Ctrl+Alt+F4,进入终端控制台,如下图所示输入startx回车,进入桌面。步骤一:找到UOS系统安装的U盘,选择U盘启动进入安装界面,如下图所示。步骤七:关机,拔出U盘,启动电脑,OK,问题解决。

Reyn_观极 1万+

C++中Inheritance的使用

C++中Inheritance的使用

网络资源是无限的 4357

深入剖析RDMA Netlink:Linux内核中高效通信的基石

RDMA Netlink:Linux内核中高效通信控制的核心机制 RDMA技术通过绕过内核实现高速数据传输,但其管理控制仍需内核参与。drivers/infiniband/core/netlink.c文件作为RDMA子系统的心脏,构建了用户空间与内核间的高效通信桥梁。该模块采用模块化客户端架构,通过全局数组管理不同类型的RDMA功能,如设备管理、连接服务和链路层操作。从最初的全局锁到细粒度读写锁的演进,展现了Linux内核追求高性能的持续优化。同时,通过条件编译支持新旧内核版本和网络命名空间,体现了稳定性与

数字人生 238

电机控制基础,小白入门篇

电机,这个藏在风扇、电动车、机器人里的“动力心脏”,如何精准控制它的转速、方向甚至力量?这篇博客专为完全零基础的小白打造,用“说人话”的方式拆解电机控制的底层逻辑,帮你从“看不懂电路图”到“能调个简单电机”。 电机控制不是“大神专属”,只要掌握“电生磁、磁生力”的底层逻辑,加上动手实践,小白也能快速入门。这篇博客会陪你从“看电机转”到“让电机听话”,把复杂的控制原理变成能上手玩的“小实验”。准备好你的面包板和电机,我们一起开启“电控之旅”吧!

汽车电子软件领域知识分享 5597

C++ 数据封装(Data Encapsulation)

数据封装(Encapsulation) 是面向对象三大特性(封装、继承、多态)中最基础、最核心的一个。核心价值(为什么必须掌握):不封装的后果(反例): 2. 数据封装的概念与三大目标 三大目标:struct vs class 默认区别(最容易忽略):现代 C++ 推荐:一律用 class,显式写 public / private。 4.2 常量成员函数(const 方法) 4.3 Pimpl 模式(Pointer to Implementation)——最高级封装 隐藏所有私有实现,只暴露接口。empl

专注于前沿技术的探索与实践,热衷于从代码逻辑、架构设计到行业应用等多维度深挖技术本质。期待在技术之路上与你共同成长~ 1031

基于 YOLOv26 的校园安全监控系统:多场景应用

本文提出了一种基于YOLOv26的校园安全监控系统,采用多场景应用架构实现对校园安全的智能监测。系统核心技术包括YOLOv26目标检测、DeepSORT目标跟踪、区域安全定义和行为分析等模块,通过边缘计算平台实现实时处理。研究构建了包含多种校园场景的专业数据集,并采用数据增强技术提升模型性能。系统可检测人员、车辆和物品等目标,分析其行为轨迹,评估安全风险并触发告警。实验结果表明,该系统能有效识别校园安全隐患,为安全管理提供智能化解决方案。

一键难忘的博客 503

在C++中的封装(Encapsulation)

C++封装机制是面向对象编程的核心,通过类将数据(成员变量)和操作(成员函数)捆绑,并使用访问修饰符(public/private/protected)控制访问权限。私有成员只能内部访问,保护数据安全;公有成员提供外部接口;保护成员允许子类访问。封装优势包括数据隐藏、接口分离和提高可维护性。继承时访问权限可能调整,友元机制可破坏封装性(慎用)。合理设计访问权限是实现安全高效代码的关键。

qq2745567641的博客 563

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

封装(Encapsulation)

在这个例子中,Person类封装了私有的name和age数据成员,并提供了公共的访问器和修改器来操作这些数据成员。外部代码可以通过调用访问器和修改器函数来访问和修改对象的状态,而无法直接访问或修改私有数据成员。不同的对象之间相互独立,各自负责自己的功能,减少了代码之间的耦合性,方便代码的维护和扩展。通过封装,可以将常用的功能和操作封装成类的成员函数,实现代码的复用。封装可以隐藏对象的内部实现细节,只暴露必要的接口,使得对象对外部的调用者来说更加简单和可理解。这有助于提高代码的安全性和可靠性。

缺点灵气儿的笔记本 983

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

封装Encapsulation继承Inheritance多态Polymorphism

封装Encapsulation继承Inheritance多态Polymorphism 一些c++与java的Interesting point.记录下感悟。 自己的总结与思考,目前水平有限,若有建议欢迎指教! cpp代码 #include <stdio.h> #include <iostream> using namespace std; // 我们假设需求是给father多添加功能,这个功能需要多加一个新的参数 class father{ private: int memb

Xiaobaiforgod的博客 606

【C++】C++核心知识:Class类-Encapsulation封装(附案例)

C++核心知识:Class类-Encapsulation封装(附案例)

weixin_73185295的博客 454

C++中Encapsulation的使用

C++中Encapsulation的使用

网络资源是无限的 2359

面向对象---封装(Encapsulation)

首先我们定义一个Person类的对象,里面放入人的相关信息   我们再从外部用对象调用person类里面其中的一个年龄,进行访问输出   这时候我们就发现了一个问题,要是我们从外部传入一个负数进来呢,这是不合逻辑的 其次我们就在person类中把age私有化   但是私有化却只能在内类中访问,外部无法访问   我们就要在person类中建立一个访问方法   一般来说,一个事物...

diaozu0707的博客 184

为何要用封装(Encapsulation)

在OO设计中,封装具有十分重要的地位,封装除了可以避免程序代码重复之外还有很多内涵,可以帮助程序员保护类免于不必要的改变。任何时候,当你认为应用程序中有某种行为很可能将来会发生改变时,你就可能需要把它从应用程序里不改变的部分移开,换言之,你应该将变化的部分封装起来。示例:Public class Painter {    public void prepareEasel() {

me_nobody的专栏 362

1.1a. 封装 (Encapsulation) 概念

封装是面向对象编程的第一大支柱,它通过class将C语言中松散的数据和函数,整合成一个高内聚、低耦合的逻辑单元。将数据(状态)和方法(行为)捆绑在一起。使用 public定义稳定接口,使用 private隐藏实现细节,保护内部状态。通过构造函数保证对象的有效初始化,通过析构函数保证资源的自动释放(RAII在嵌入式开发中,封装的意义尤为重大。它让我们能够创建出像GpioPinI2CDeviceTimer这样的硬件抽象层(HAL),这些抽象层接口清晰、使用安全、内部实现与上层应用完全隔离。

Rach的博客 1223

python:封装(Encapsulation)

python:封装(Encapsulation)

听海边涛声 979

C语言模拟面向对象三大特性与C++实现对比

特性C语言实现方式C++实现方式底层共性原理封装不透明指针+访问函数数据隐藏+接口暴露继承结构体嵌套(基类成员作为首成员)内存布局叠加+成员复用多态函数指针表+基类指针强制转换virtual函数 + 虚函数表(vtable)动态绑定+接口统一实现各异C语言模拟OO的本质:通过结构体组合、函数指针和编程约定实现面向对象特性,需手动管理所有细节。C++的语法优势:编译器自动处理vtable、构造/析构顺序、访问控制等,减少手动错误。内存布局相似性。

码事漫谈 1603

Cpp面向对象概念-笔记

Cpp面向对象概念Object-Oriented Concepts本文参考此处 Object Class Abstraction Encapsulation Inheritance Polymorphism Overloading Object数据(data)和函数(操作)的捆绑单元,就是对象。ClassblueprintAbstraction抽象指的是,只向外面提供必须的信息,而把内部细节隐藏起来

XXXXX的专栏 1710

C++语言学习(三)——封装(Encapsulation)

C++语言学习(三)——封装(Encapsulation) 一、封装简介 C语言等面向过程编程中,数据以及数据的相关操作函数都是分离的独立个体;在C++等面向对象编程中,数据以及数据的相关操作被设计为对象,对象包括属性(数据)和操作(函数),两者共同构成对象实体(即类实体)。面向对象编程使程序更模块化,更易读易写,提升了代码重用到一个更高的层次。面向对象编程中,数据和数据的操作封装为了对象。封装可...

weixin_33859504的博客 481

Lab0回顾:encapsulation的概念

做个记录。

feiyu66666的博客 458
上一篇: Ubuntu20.04中编译seetaFaceEngine
下一篇: 二、C++面向对象-继承(Inheritance)
木子21
博客等级 码龄9年 58粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值