Objects and Classes (对象和类)

Objects and Classes [对象和类]

  • 1. Procedural and Object-Oriented Programming (过程性编程和面向对象编程)
  • 2. Abstraction and Classes (抽象和类)
    • 2.1. Classes in C++ (C++ 中的类)
    • 2.2. Implementing Class Member Functions (实现类成员函数)
    • 2.3. Using Classes
  • References

Object-oriented programming (OOP) is a particular conceptual approach to designing programs, and C++ has enhanced C with features that ease the way to applying that approach.
面向对象编程 (OOP) 是一种特殊的、设计程序的概念性方法,C++ 通过一些特性改进了 C 语言,使得应用这种方法更容易。

ease [iːz]:v. 缓解,减轻,放松,降低 n. 容易,安逸,自在,舒适

The following are the most important OOP features:

  • Abstraction (抽象)
  • Encapsulation and data hiding (封装和数据隐藏)
  • Polymorphism (多态)
  • Inheritance (继承)
  • Reusability of code (代码的可重用性)

The class is the single most important C++ enhancement for implementing these features and tying them together.
为了实现这些特性并将它们组合在一起,C++ 所做的最重要的改进是提供了类。

1. Procedural and Object-Oriented Programming (过程性编程和面向对象编程)

In short, with a procedural approach, you first concentrate on the procedures you will follow and then think about how to represent the data.
采用过程性编程方法时,首先考虑要遵循的步骤,然后考虑如何表示这些数据。

In short, with an OOP approach, you concentrate on the object as the user perceives it, thinking about the data you need to describe the object and the operations that will describe the user’s interaction with the data. After you develop a description of that interface, you move on to decide how to implement the interface and data storage. Finally, you put together a program to use your new design.
采用 OOP 方法时,首先从用户的角度考虑对象,描述对象所需的数据以及描述用户与数据交互所需的操作。完成对接口的描述后,需要确定如何实现接口和数据存储。最后,使用新的设计方案创建出程序。

perceive [pə(r)ˈsiːv]:v. 认为,意识到,注意到,察觉到

2. Abstraction and Classes (抽象和类)

Life is full of complexities, and one way we cope with complexity is to frame simplifying abstractions. From abstraction, it is a short step to the user-defined type, which in C++ is a class design that implements the abstract interface.
生活中充满复杂性,处理复杂性的方法之一是简化和抽象。抽象是通往用户定义类型的捷径,在 C++ 中,用户定义类型指的是实现抽象接口的类设计。

For built-in types, the information about operations is built in to the compiler. But when you define a user-defined type in C++, you have to provide the same kind of information yourself. In exchange for this extra work, you gain the power and flexibility to custom fit new data types to match real-world requirements.
对于内置类型来说,有关操作的信息被内置到编译器中。但在 C++ 中定义用户自定义的类型时,必须自己提供这些信息。付出这些劳动换来了根据实际需要定制新数据类型的强大功能和灵活性。

2.1. Classes in C++ (C++ 中的类)

A class is a C++ vehicle for translating an abstraction to a user-defined type. It combines data representation and methods for manipulating that data into one neat package.
类是一种将抽象转换为用户定义类型的 C++ 工具,它将数据表示和操纵数据的方法组合成一个整洁的包。

Generally, a class specification has two parts:

  • A class declaration, which describes the data component, in terms of data members, and the public interface, in terms of member functions, termed methods
    类声明:以数据成员的方式描述数据部分,以成员函数 (被称为方法) 的方式描述公有接口。

  • The class method definitions, which describe how certain class member functions are implemented
    类方法定义:描述如何实现类成员函数。

Roughly speaking, the class declaration provides a class overview, whereas the method definitions supply the details.
类声明提供了类的蓝图,而方法定义则提供了细节。

An interface is a shared framework for interactions between two systems. But in any case, to use a class, you need to know its public interface; to write a class, you need to create its public interface.
接口是一个共享框架,供两个系统交互时使用。要使用某个类,必须了解其公共接口;要编写类,必须创建其公共接口。

Typically, C++ programmers place the interface, in the form of a class definition, in a header file and place the implementation, in the form of code for the class methods, in a source code file.
C++ 程序员将接口 (类定义) 放在头文件中,并将实现 (类方法的代码) 放在源代码文件中。

In this context the keywords class and typename are not synonymous the way they were in template parameters; typename can’t be used here.
C++ 关键字 class 指出这些代码定义了一个类设计,在这里关键字 classtypename 不是同义词,不能使用 typename 代替 class (不同于在模板参数中)。Stock 是这个新类的类型名,该声明让我们能够声明 Stock 类型的变量称为对象或实例。

#ifndef STOCK_H_
#define STOCK_H_#include <string>// class declaration
class Stock {
private:std::string company;int shares;double share_val;double total_val;void SetTot() { total_val = shares * share_val; }
public:Stock(); // Default constructorStock(const std::string &company, const long num = 0, const double price = 0.0);~Stock();void Buy(const long num, const double price);void Sell(const long num, const double price);void Update(const double price);void Show()const;const Stock &Topval(const Stock &stock) const;
}; // Note semicolon at the end#endif

1. Access Control (访问控制)

Also new are the keywords private and public. These labels describe access control for class members. Any program that uses an object of a particular class can access the public portions directly. A program can access the private members of an object only by using the public member functions (or via a friend function). For example, the only way to alter the shares member of the Stock class is to use one of the Stock member functions. Thus, the public member functions act as go-betweens between a program and an object’s private members; they provide the interface between object and program. This insulation of data from direct access by a program is called data hiding.
关键字 privatepublicprotected 描述了对类成员的访问控制。使用类对象的程序都可以直接访问公有部分,但只能通过公有成员函数 (或友元函数) 来访问对象的私有成员。例如,要修改 Stock 类的 shares 成员,只能通过 Stock 的成员函数。因此,公有成员函数是程序和对象的私有成员之间的桥梁,提供了对象和程序之间的接口。防止程序直接访问数据被称为数据隐藏。

insulation [ˌɪnsjʊˈleɪʃ(ə)n]:n. 绝缘,隔热,隔音,隔热材料

在这里插入图片描述

The Stock class.

A class design attempts to separate the public interface from the specifics of the implementation. The public interface represents the abstraction component of the design. Gathering the implementation details together and separating them from the abstraction is called encapsulation. Data hiding (putting data into the private section of a class) is an instance of encapsulation, and so is hiding functional details of an implementation in the private section, as the Stock class does with SetTot(). Another example of encapsulation is the usual practice of placing class function definitions in a separate file from the class declaration.
类设计尽可能将公有接口与实现细节分开。公有接口表示设计的抽象组件,将实现细节放在一起并将它们与抽象分开被称为封装。数据隐藏 (将数据放在类的私有部分中) 是一种封装,将实现的细节隐藏在私有部分中,就像 Stock 类对 SetTot() 所做的那样,也是一种封装。封装的另一个例子是将类函数定义和类声明放在不同的文件中。

OOP is a programming style that you can use to some degree with any language.
OOP 是一种编程风格,从某种程度说,它用于任何一种语言中。

Note that data hiding not only prevents you from accessing data directly, but it also absolves you (in the roll as a user of the class) from needing to know how the data is represented.
数据隐藏不仅可以防止直接访问数据,还让开发者 (类的用户) 无需了解数据是如何被表示的。

absolve [əbˈzɒlv]:v. 宣告 ... 无罪,判定 ... 无责,赦免 ... 的罪

2. Member Access Control (控制对成员的访问)

You can declare class members, whether they are data items or member functions, either in the public or the private section of a class. But because one of the main precepts of OOP is to hide the data, data items normally go into the private section. The member functions that constitute the class interface go into the public section; otherwise, you can’t call those functions from a program. As the Stock declaration shows, you can also put member functions in the private section. You can’t call such functions directly from a program, but the public methods can use them. Typically, you use private member functions to handle implementation details that don’t form part of the public interface.
无论类成员是数据成员还是成员函数,都可以在类的公有部分或私有部分中声明它。但由于隐藏数据是 OOP 主要的目标之一,因此数据项通常放在私有部分,组成类接口的成员函数放在公有部分;否则,就无法从程序中调用这些函数。正如 Stock 声明所表明的,也可以把成员函数放在私有部分中。不能直接从程序中调用这种函数,但公有方法却可以使用它们。通常,程序员使用私有成员函数来处理不属于公有接口的实现细节。

You don’t have to use the keyword private in class declarations because that is the default access control for class objects:

class World
{float mass; // private by defaultchar name[20]; // private by default
public:void tellall(void);...
};

However, this book explicitly uses the private label in order to emphasize the concept of data hiding.
然而,为强调数据隐藏的概念,本书显式地使用了 private

Class descriptions look much like structure declarations with the addition of member functions and the public and private visibility labels. In fact, C++ extends to structures the same features classes have. The only difference is that the default access type for a structure is public, whereas the default type for a class is private. C++ programmers commonly use classes to implement class descriptions while restricting structures to representing pure data objects (often called plain-old data structures, or POD structures).
类描述看上去很像是包含成员函数以及 publicprivate 可见性标签的结构声明。实际上,C++ 对 struct 进行了扩展,使之具有与 class 相同的特性。它们之间唯一的区别是,struct 的默认访问类型是 public,而 class 的默认访问类型为 privateC++ 程序员通常使用类来实现类描述,而把结构限制为只表示纯粹的数据对象,常被称为普通老式数据结构 (Plain Old Data,POD)。

2.2. Implementing Class Member Functions (实现类成员函数)

Member function definitions are much like regular function definitions. Each has a function header and a function body. Member function definitions can have return types and arguments. But they also have two special characteristics:

  • When you define a member function, you use the scope-resolution operator (::) to identify the class to which the function belongs.
    定义成员函数时,使用作用域解析运算符 (::) 来标识函数所属的类。
  • Class methods can access the private components of the class.
    类方法可以访问类的 private 组件。

The function header for a member function uses the scope-resolution operator (::) to indicate to which class the function belongs.
成员函数的函数头使用作用域运算符解析 (::) 来指出函数所属的类。

For example, the header for the Update() member function looks like this:

void Stock::Update(double price)

This notation means you are defining the Update() function that is a member of the Stock class. Not only does this identify Update() as a member function, it means you can use the same name for a member function for a different class.

For example, an Update() function for a Buffoon class would have this function header:

void Buffoon::Update()

Thus, the scope-resolution operator resolves the identity of the class to which a method definition applies. We say that the identifier Update() has class scope. Other member functions of the Stock class can, if necessary, use the Update() method without using the scope-resolution operator. That’s because they belong to the same class, making Update() in scope.
因此,作用域解析运算符确定了方法定义对应的类的身份。我们说,标识符 Update() 具有类作用域 (class scope)。Stock 类的其他成员函数不必使用作用域解析运算符就可以使用 Update() 方法,这是因为它们属于同一个类, 因此 Update() 是可见的。

One way of looking at method names is that the complete name of a class method includes the class name. Stock::Update() is called the qualified name of the function. A simple Update(), on the other hand, is an abbreviation (the unqualified name) for the full name - one that can be used just in class scope.
类方法的完整名称中包括类名。Stock::Update() 是函数的限定名 (qualified name),而简单的 Update() 是全名的缩写 (非限定名,unqualified name) ,它只能在类作用域中使用。

The second special characteristic of methods is that a method can access the private members of a class.
方法可以访问类的私有成员。

If you try to use a nonmember function to access these data members, the compiler stops you cold in your tracks. (However, friend functions provide an exception.)
如果试图使用非成员函数访问这些数据成员,编译器禁止这样做 (友元函数例外) 。

1. Member Function Notes (成员函数说明)

Because this function is merely the means of implementing the code and not part of the public interface, the class makes SetTot() a private member function. (That is, SetTot() is a member function used by the person writing the class but not used by someone writing code that uses the class.)
由于 SetTot() 只是实现代码的一种方式,而不是公有接口的组成部分,因此这个类将其声明为私有成员函数 ( 即编写这个类的人可以使用它, 但编写代码来使用这个类的人不能使用) 。

2. Inline Methods (内联方法)

Any function with a definition in the class declaration automatically becomes an inline function. Thus, Stock::SetTot() is an inline function. Class declarations often use inline functions for short member functions, and SetTot() qualifies on that account.
定义位于类声明中的函数都将自动成为内联函数,因此 Stock::SetTot() 是一个内联函数。类声明常将短小的成员函数作为内联函数,SetTot() 符合这样的要求。

You can, if you like, define a member function outside the class declaration and still make it inline. To do so, you just use the inline qualifier when you define the function in the class implementation section:
如果愿意,也可以在类声明之外定义成员函数,并使其成为内联函数。为此,只需在类实现部分中定义函数时使用 inline 限定符即可:

class Stock
{
private:...void SetTot(); // definition kept separate
public:...
};inline void Stock::SetTot() // use inline in definition
{total_val = shares * share_val;
}

The special rules for inline functions require that they be defined in each file in which they are used. The easiest way to make sure that inline definitions are available to all files in a multifile program is to include the inline definition in the same header file in which the corresponding class is defined.
内联函数的特殊规则要求在每个使用它们的文件中都对其进行定义。确保内联定义对多文件程序中的所有文件都可用的、最简便的方法是:将内联定义放在定义类的头文件中 。

Incidentally, according to the rewrite rule, defining a method within a class declaration is equivalent to replacing the method definition with a prototype and then rewriting the definition as an inline function immediately after the class declaration. That is, the original inline definition of SetTot() is equivalent to the one just shown, with the definition following the class declaration.
根据改写规则 (rewrite rule),在类声明中定义方法等同于用原型替换方法定义,然后在类声明的后面将定义改写为内联函数。程序清单中 SetTot() 的内联定义与上述代码 (定义紧跟在类声明之后) 是等价的。

When you call a member function, it uses the data members of the particular object used to invoke the member function.
调用成员函数时,它将使用被用来调用它的对象的数据成员。

Each new object you create contains storage for its own internal variables, the class members. But all objects of the same class share the same set of class methods, with just one copy of each method.
所创建的每个新对象都有自己的存储空间,用于存储其内部变量和类成员;但同一个类的所有对象共享同一组类方法,即每种方法只有一个副本。

They just apply the code to different data. Calling a member function is what some OOP languages term sending a message. Thus, sending the same message to two different objects invokes the same method but applies it to two different objects
它们将执行同一个代码块,只是将这些代码用于不同的数据。在 OOP 中,调用成员函数被称为发送消息,因此将同样的消息发送给两个不同的对象将调用同一个方法,但该方法被用于两个不同的对象。

在这里插入图片描述

Objects, data, and member functions.

2.3. Using Classes

The C++ goal is to make using classes as similar as possible to using the basic, built-in types, such as int and char. You can create a class object by declaring a class variable or using new to allocate an object of a class type.
C++ 的目标是使得使用类与使用基本的内置类型 (例如 intchar) 尽可能相同。要创建类对象,可以声明类变量,也可以使用 new 为类对象分配存储空间。

1. The Client / Server Model

OOP programmers often discuss program design in terms of a client / server model. In this conceptualization, the client is a program that uses the class. The class declaration, including the class methods, constitute the server, which is a resource that is available to the programs that need it. The client uses the server through the publicly defined interface only. This means that the client’s only responsibility, and, by extension, the client’s programmer’s only responsibility, is to know that interface. The server’s responsibility, and, by extension, the server’s designer’s responsibility, is to

see that the server reliably and accurately performs according to that interface. Any changes the server designer makes to the class design should be to details of implementation, not to the interface. This allows programmers to improve the client and the server independently of each other, without changes in the server having unforeseen repercussions on the client’s behavior.
OOP 程序员常依照客户/服务器模型来讨论程序设计。在这个概念中,客户是使用类的程序。类声明 (包括类方法) 构成了服务器,它是程序可以使用的资源。客户只能通过以公有方式定义的接口使用服务器,这意味着客户 (客户程序员) 唯一的责任是了解该接口。服务器 (服务器设计人员) 的责任是确保服务器根据该接口可靠并准确地执行。服务器设计人员只能修改类设计的实现细节,而不能修改接口。这样程序员独立地对客户和服务器进行改进,对服务器的修改不会客户的行为造成意外的影响。

You can avoid e-notation by using the setf() method

std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);

This sets a flag in the std::cout object instructing cout to use fixed-point notation.
设置 std::cout 对象的一个标记,命令 std::cout 使用定点表示法。使用方法 std::cout.setf(),便可避免科学计数法

Similarly, the following statement causes std::cout to show three places to the right of the decimal when using fixed-point notation.
下面的语句设置 std::cout 在使用定点表示法时,显示 3 位小数

std::cout.precision(3);

The class declaration is modeled after a structure declaration and can include data members and function members. The declaration has a private section, and members declared in that section can be accessed only through the member functions. The declaration also has a public section, and members declared there can be accessed directly by a program using class objects.
类声明类似结构声明,可以包括数据成员和函数成员。声明私有部分,在其中声明的成员只能通过成员函数进行访问;声明公有部分,在其中声明的成员可被使用类对象的程序直接访问。通常,数据成员被放在私有部分中,成员函数被放在公有部分中。

Typically, data members go into the private section and member functions go into the public section, so a typical class declaration has this form:

class className
{
private:data member declarations
public:member function prototypes
};

The contents of the public section constitute the abstract part of the design, the public interface. Encapsulating data in the private section protects the integrity of the data and is called data hiding.
公有部分的内容构成了设计的抽象部分 - 公有接口。将数据封装到私有部分中可以保护数据的完整性,这被称为数据隐藏。

You can use a complete function definition instead of a function prototype in the class declaration, but the usual practice, except with very brief functions, is to provide the function definitions separately. In that case, you need to use the scope-resolution operator to indicate to which class a member function belongs.
可以在类声明中提供完整的函数定义,而不是函数原型,但是通常的做法是单独提供函数定义 (除非函数很小)。在这种情况下,需要使用作用域解析运算符来指出成员函数属于哪个类。

For example, suppose the Bozo class has a member function called Retort() that returns a pointer to a char. The function header would look like this:

char * Bozo::Retort()

In other words, Retort() is not just a type char * function; it is a type char * function that belongs to the Bozo class. The full, or qualified, name of the function is Bozo::Retort().The name Retort(), on the other hand, is an abbreviation of the qualified name, and it can be used only in certain circumstances, such as in the code for the class methods.
Retort() 不仅是一个 char * 类型的函数,而是一个属于 Bozo 类的 char * 函数。该函数的全名 (或限定名) 为 Bozo::Retort()。而名称 Retort() 是限定名的缩写,只能在某些特定的环境中使用。

The name Retort() has class scope, so the scope-resolution operator is needed to qualify the name when it is used outside the class declaration and a class method.
名称 Retort() 的作用域为整个类,因此在类声明和类方法之外使用该名称时,需要使用作用域解析运算符进行限定。

要创建对象 (类的实例),只需将类名视为类型名即可:

Bozo bozetta;

This works because a class is a user-defined type. You invoke a class member function, or method, by using a class object. You do so by using the dot membership operator: std::cout << Bozetta.Retort();
这样做是可行的,因为类是用户定义的类型。类成员函数 (方法) 可通过类对象来调用。为此,需要使用成员运算符句点。

This invokes the Retort() member function, and whenever the code for that function refers to a particular data member, the function uses the value that member has in the bozetta object.
这将调用 Retort() 成员函数,每当其中的代码引用某个数据成员时,该函数都将使用 bozetta 对象中相应成员的值。

References

[1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/
[2] C++ Primer Plus, 6th Edition, https://www.informit.com/store/c-plus-plus-primer-plus-9780321776402

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/861449.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Renesas MCU使用SCI_I2C驱动HS3003

目录 概述 1 软硬件介绍 1.1 软件版本信息 1.2 认识HS3003 1.2.1 HS3003特性 1.2.2 HS3003寄存器 1.2.2.1 温湿度数据寄存器 1.2.2.2 参数寄存器 1.2.2.3 一个参数配置Demo 1.2.3 温湿度值转换 1.2.4 HS3003应用电路 1.2.4.1 PIN引脚定义 1.2.4.2 sensor 应用电路 …

Django-开发一个列表页面

需求 基于ListView,创建一个列表视图,用于展示"BookInfo"表的信息要求提供分页提供对书名,作者,描述的查询功能 示例展示: 1. 数据模型 models.py class BookInfo(models.Model):titlemodels.CharField(verbose_name"书名",max_length100)authormode…

【八股系列】Vue中的<keep-alive>组件:深入解析与实践指南

&#x1f389; 博客主页&#xff1a;【剑九 六千里-CSDN博客】 &#x1f3a8; 上一篇文章&#xff1a;【探索响应式布局的奥秘&#xff1a;关键技术与实战代码示例】 &#x1f3a0; 系列专栏&#xff1a;【面试题-八股系列】 &#x1f496; 感谢大家点赞&#x1f44d;收藏⭐评论…

正则表达式;grep、sed、awk、soft、uniq、tr 详解

正则表达式 概念 正则表达式&#xff08;Regular Expression&#xff0c;常简写为regex、regexp或RE&#xff09;是一种强大的文本处理工具&#xff0c;它使用一种特殊的字符序列来帮助用户检查一个字符串是否与某种模式匹配。 标准正则表达式 首先安装正则表达式pcre库 创…

C++ | Leetcode C++题解之第200题岛屿数量

题目&#xff1a; 题解&#xff1a; class Solution { private:void dfs(vector<vector<char>>& grid, int r, int c) {int nr grid.size();int nc grid[0].size();grid[r][c] 0;if (r - 1 > 0 && grid[r-1][c] 1) dfs(grid, r - 1, c);if (r …

Shell 编程入门

优质博文&#xff1a;IT-BLOG-CN 【1】x.sh文件内容编写&#xff1a; 固定开头&#xff1a;#&#xff01;/bin/sh&#xff1b; 【2】学习的第一个命令就是echo输出的意思&#xff1b; 【3】其实shell脚本也就是在文件中写命令&#xff0c;但是我们要写的是绝对路径&#xff1a…

mysql岗位实习----教务系统管理

教务管理系统 一、DDL CREATE TABLE users (user_id int(11) NOT NULL AUTO_INCREMENT COMMENT 用户ID,username varchar(50) NOT NULL COMMENT 用户名,password varchar(255) NOT NULL COMMENT 密码,gender enum(男,女) NOT NULL COMMENT 性别,email varchar(100) DEFAULT N…

C++初学者指南第一步---14.函数调用机制

C初学者指南第一步—14.函数调用机制 文章目录 C初学者指南第一步---14.函数调用机制1.记住&#xff1a;内存的结构2.函数调用是如何工作的3. 不要引用局部变量4. 常见编译器优化5. Inlining内联 1.记住&#xff1a;内存的结构 堆&#xff08;自由存储&#xff09; 用于动态存…

Redis-实战篇-缓存雪崩

文章目录 1、缓存雪崩2、解决方案&#xff1a; 1、缓存雪崩 缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 2、解决方案&#xff1a; 给不同的key的TTL添加随机值利用Redis集群提高服务的可用性…

华为电脑重装系统如何操作?电脑Win11系统重装注意什么?图文详细解答

随着科技的不断进步&#xff0c;操作系统更新换代的步伐也日益加快。华为电脑作为市场中的佼佼者&#xff0c;其搭载的Windows 11系统凭借其强大的性能和丰富的功能受到了用户的广泛好评。然而&#xff0c;随着使用时间的推移&#xff0c;系统可能会出现各种问题&#xff0c;如…

验证码技术 easy-captcha

依赖 <!-- easy-captcha用来生成验证码&#xff0c;由于jdk9以后&#xff0c;内置JavaScript去掉了&#xff0c;所以需要导入这个org.openjdk.nashorn --> <dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</arti…

牛客挑战赛75 D. 不存在的玩家(sg图dp)

题目 思路来源 灵茶山群群友 https://blog.csdn.net/Code92007/article/details/110354429 题解 其实想了想&#xff0c;和20年小米邀请赛决赛这个G题的dp思路是一样的&#xff0c;姑且称为sg图dp吧 按sg值从大到小dp&#xff0c;每次补上全局sg值-1的这些点&#xff0c; …

网约车停运损失费:2、协商过程

目录 &#x1f345;点击这里查看所有博文 随着自己工作的进行&#xff0c;接触到的技术栈也越来越多。给我一个很直观的感受就是&#xff0c;某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了&#xff0c;只有经常会用到的东西才有可能真正记…

Houdini 通过wedge来做模拟参数对比 (PDG TOP)

我们的设定如下例子 这是个简单的布料悬挂的例子。上方两个角分别被固定住了&#xff0c;然后在distance约束下布料下垂。 我们现在的目的是想要对比不同的streach stiffness对模拟的影响。 第一步&#xff1a;找到stiffness参数&#xff0c;右键expression->edit expre…

iis控制文件或者文件夹是否允许被访问

问题 出于数据或者网络安全&#xff0c;禁止扫描工具直接扫描到某些包含敏感信息的文件&#xff0c;尤其比如日志、配置&#xff0c;如何不写代码&#xff0c;使用iis处理呢&#xff1f; 假设有如下网站&#xff0c;访问http://localhost:6001/Logs/20240626.txt就会出现日志&…

AI开发Windows环境搭建

文章目录 1. GPU 支持检查2. 安装 Anaconda3. 创建 PyTorch 虚拟环境3.2 创建虚拟 PyTorchEnv 环境3.3 检查、激活、推出虚拟环境3.4 虚拟环境中python包管理3.5 虚拟环境中安装 PyTorch 框架 4. TensorFlow 安装 1. GPU 支持检查 打开 Task Manager (任务管理器&#xff09;&…

DPDK使用make编译并运行示例程序

环境&#xff1a; VMware Workstation 16 Pro 16.2.4 虚拟机系统&#xff1a;Centos 8 DPDK版本&#xff1a;stable-20.11.10 下载源码后&#xff0c;使用meson和ninja编译完成、配置并挂载大页、内核和VFIO设置完成&#xff0c;在dpdk源码目录下的build/…

docker搭建mongo分片集群

1、mongo分片集群 MongoDB分片集群是一种可扩展的数据库架构&#xff0c;用于处理大量数据和高并发访问。它将数据分成多个分片&#xff0c;并将这些分片分布在多个服务器上&#xff0c;从而实现数据的平衡存储和并行处理 。 通过使用MongoDB的分片集&#xff0c;可以实现数据…

NestJs 使用 RabbitMQ

NestJs 使用 RabbitMQ 既然是使用 RabbitMQ 那先不管其他的 把 RabbitMQ 装上再说 RabbitMQ 安装 这里直接找他们官网就行 Installing RabbitMQ | RabbitMQ 这里我们选择使用 docker 安装 快捷方便 这里直接参考&#xff1a; https://juejin.cn/post/719843080185010591…

鸿蒙面试心得

自疫情过后&#xff0c;java和web前端都进入了冰河时代。年龄、薪资、学历都成了找工作路上躲不开的门槛。 年龄太大pass 薪资要高了pass 学历大专pass 好多好多pass 找工作的路上明明阳关普照&#xff0c;却有一种凄凄惨惨戚戚说不清道不明的“优雅”意境。 如何破局&am…