Scope, Duration, and Linkage___CH_6

2023-11-19

Each project corresponds to one program. 

6.1 — Compound statements (blocks)

A compound statement (also called a block, or block statement) is a group of zero or more statements that is treated by the compiler as if it were a single statement.

Block nesting levels

Best practice

Keep the nesting level of your functions to 3 or less. If your function has a need for more nested levels, consider refactoring your function into sub-functions.

6.2 — User-defined namespaces and the scope resolution operator

Using the scope resolution operator with no name prefix

The scope resolution operator can also be used in front of an identifier without providing a namespace name (e.g. ::doSomething). In such a case, the identifier (e.g. doSomething) is looked for in the global namespace.

#include <iostream>

void print() // this print lives in the global namespace
{
	std::cout << " there\n";
}

namespace foo
{
	void print() // this print lives in the foo namespace
	{
		std::cout << "Hello";
	}
}

int main()
{
	foo::print(); // call print() in foo namespace
	::print(); // call print() in global namespace (same as just calling print() in this case)

	return 0;
}

In the above example, the ::print() performs the same as if we’d called print() with no scope resolution, so use of the scope resolution operator is superfluous in this case. But the next example will show a case where the scope resolution operator with no namespace can be useful.

Identifier resolution from within a namespace

If an identifier inside a namespace is used and no scope resolution is provided, the compiler will first try to find a matching declaration in that same namespace. If no matching identifier is found, the compiler will then check each containing namespace in sequence to see if a match is found, with the global namespace being checked last.

#include <iostream>

void print() // this print lives in the global namespace
{
	std::cout << " there\n";
}

namespace foo
{
	void print() // this print lives in the foo namespace
	{
		std::cout << "Hello";
	}

	void printHelloThere()
	{
		print(); // calls print() in foo namespace
		::print(); // calls print() in global namespace
	}
}

int main()
{
	foo::printHelloThere();

	return 0;
}

This prints:

Hello there

In the above example, print() is called with no scope resolution provided. Because this use of print() is inside the foo namespace, the compiler will first see if a declaration for foo::print() can be found. Since one exists, foo::print() is called.

If foo::print() had not been found, the compiler would have checked the containing namespace (in this case, the global namespace) to see if it could match a print() there.

Note that we also make use of the scope resolution operator with no namespace (::print()) to explicitly call the global version of print().

Multiple namespace blocks are allowed

Warning

Do not add custom functionality to the std namespace.

Namespace aliases

One nice advantage of namespace aliases: If you ever want to move the functionality within foo::goo to a different place, you can just update the active alias to reflect the new destination, rather than having to find/replace every instance of foo::goo.

When you should use namespaces

6.3 — Local variables

Local variables have automatic storage duration

Local variables have no linkage

Variables should be defined in the most limited scope

Best practice

Define variables in the most limited existing scope. Avoid creating new blocks whose only purpose is to limit the scope of variables.

6.4 — Introduction to global variables

Declaring and naming global variables

Best practice

Consider using a “g” or “g_” prefix when naming non-const global variables, to help differentiate them from local variables and function parameters.

Global variables have file scope and static duration

Global variables are created when the program starts, and destroyed when it ends. This is called static duration. Variables with static duration are sometimes called static variables.

Global variable initialization

Constant global variables

Quick Summary

// Non-constant global variables
int g_x;                 // defines non-initialized global variable (zero initialized by default)
int g_x {};              // defines explicitly zero-initialized global variable
int g_x { 1 };           // defines explicitly initialized global variable

// Const global variables
const int g_y;           // error: const variables must be initialized
const int g_y { 2 };     // defines initialized global constant

// Constexpr global variables
constexpr int g_y;       // error: constexpr variables must be initialized
constexpr int g_y { 3 }; // defines initialized global const

6.5 — Variable shadowing (name hiding)

Each block defines its own scope region. So what happens when we have a variable inside a nested block that has the same name as a variable in an outer block? When this happens, the nested variable “hides” the outer variable in areas where they are both in scope. This is called name hiding or shadowing.

Avoid variable shadowing

Shadowing of local variables should generally be avoided, as it can lead to inadvertent errors where the wrong variable is used or modified. Some compilers will issue a warning when a variable is shadowed.

For the same reason that we recommend avoiding shadowing local variables, we recommend avoiding shadowing global variables as well. This is trivially avoidable if all of your global names use a “g_” prefix.

Best practice

Avoid variable shadowing.

6.6 — Internal linkage

Global variables with internal linkage

Global variables with internal linkage are sometimes called internal variables.

To make a non-constant global variable internal, we use the static keyword.

#include <iostream>

static int g_x{}; // non-constant globals have external linkage by default, but can be given internal linkage via the static keyword

const int g_y{ 1 }; // const globals have internal linkage by default
constexpr int g_z{ 2 }; // constexpr globals have internal linkage by default

int main()
{
    std::cout << g_x << ' ' << g_y << ' ' << g_z << '\n';
    return 0;
}

For advanced readers

The use of the static keyword above is an example of a storage class specifier, which sets both the name’s linkage and its storage duration (but not its scope). The most commonly used storage class specifiers are static, extern, and mutable. The term storage class specifier is mostly used in technical documentations.

The one-definition rule and internal linkage

In lesson 2.7 – Forward declarations and definitions, we noted that the one-definition rule says that an object or function can’t have more than one definition, either within a file or a program.

However, it’s worth noting that internal objects (and functions) that are defined in different files are considered to be independent entities (even if their names and types are identical), so there is no violation of the one-definition rule. Each internal object only has one definition.

Functions with internal linkage

Because linkage is a property of an identifier (not of a variable), function identifiers have the same linkage property that variable identifiers do. Functions default to external linkage (which we’ll cover in the next lesson), but can be set to internal linkage via the static keyword:

Quick Summary

// Internal global variables definitions:
static int g_x;          // defines non-initialized internal global variable (zero initialized by default)
static int g_x{ 1 };     // defines initialized internal global variable

const int g_y { 2 };     // defines initialized internal global const variable
constexpr int g_y { 3 }; // defines initialized internal global constexpr variable

// Internal function definitions:
static int foo() {};     // defines internal function

6.7 — External linkage and variable forward declarations

Functions have external linkage by default

In lesson 2.8 – Programs with multiple code files, you learned that you can call a function defined in one file from another file. This is because functions have external linkage by default.

In order to call a function defined in another file, you must place a forward declaration for the function in any other files wishing to use the function. The forward declaration tells the compiler about the existence of the function, and the linker connects the function calls to the actual function definition.

Here’s an example:

a.cpp:

#include <iostream>

void sayHi() // this function has external linkage, and can be seen by other files
{
    std::cout << "Hi!\n";
}

main.cpp:

void sayHi(); // forward declaration for function sayHi, makes sayHi accessible in this file

int main()
{
    sayHi(); // call to function defined in another file, linker will connect this call to the function definition

    return 0;
}

The above program prints:

Hi!

In the above example, the forward declaration of function sayHi() in main.cpp allows main.cpp to access the sayHi() function defined in a.cpp. The forward declaration satisfies the compiler, and the linker is able to link the function call to the function definition.

If function sayHi() had internal linkage instead, the linker would not be able to connect the function call to the function definition, and a linker error would result.

Global variables with external linkage

Global variables with external linkage are sometimes called external variables. To make a global variable external (and thus accessible by other files), we can use the extern keyword to do so:

Variable forward declarations via the extern keyword

Warning

If you want to define an uninitialized non-const global variable, do not use the extern keyword, otherwise C++ will think you’re trying to make a forward declaration for the variable.

Warning

Although constexpr variables can be given external linkage via the extern keyword, they can not be forward declared, so there is no value in giving them external linkage.

This is because the compiler needs to know the value of the constexpr variable (at compile time). If that value is defined in some other file, the compiler has no visibility on what value was defined in that other file.


Note that function forward declarations don’t need the extern keyword – the compiler is able to tell whether you’re defining a new function or making a forward declaration based on whether you supply a function body or not. Variables forward declarations do need the extern keyword to help differentiate variables definitions from variable forward declarations (they look otherwise identical):

// non-constant
int g_x; // variable definition (can have initializer if desired)
extern int g_x; // forward declaration (no initializer)

// constant
extern const int g_y { 1 }; // variable definition (const requires initializers)
extern const int g_y; // forward declaration (no initializer)

File scope vs. global scope

The terms “file scope” and “global scope” tend to cause confusion, and this is partly due to the way they are informally used. Technically, in C++, all global variables have “file scope”, and the linkage property controls whether they can be used in other files or not.

Quick summary

// External global variable definitions:
int g_x;                       // defines non-initialized external global variable (zero initialized by default)
extern const int g_x{ 1 };     // defines initialized const external global variable
extern constexpr int g_x{ 2 }; // defines initialized constexpr external global variable

// Forward declarations
extern int g_y;                // forward declaration for non-constant global variable
extern const int g_y;          // forward declaration for const global variable
extern constexpr int g_y;      // not allowed: constexpr variables can't be forward declared

Quiz time

Question #1

What’s the difference between a variable’s scope, duration, and linkage? What kind of scope, duration, and linkage do global variables have?

Scope determines where a variable is accessible. Duration determines when a variable is created and destroyed. Linkage determines whether the variable can be exported to another file or not.

Global variables have global scope (aka. file scope), which means they can be accessed from the point of declaration to the end of the file in which they are declared.

Global variables have static duration, which means they are created when the program is started, and destroyed when it ends.

Global variables can have either internal or external linkage, via the static and extern keywords respectively.

6.8 — Why (non-const) global variables are evil

Why (non-const) global variables are evil

One of the key reasons to declare local variables as close to where they are used as possible is because doing so minimizes the amount of code you need to look through to understand what the variable does. Global variables are at the opposite end of the spectrum – because they can be accessed anywhere, you might have to look through the entire program to understand their usage. In small programs, this might not be an issue. In large ones, it will be.

Best practice

Use local variables instead of global variables whenever possible.

The initialization order problem of global variables

Warning

Dynamic initialization of global variables causes a lot of problems in C++. Avoid dynamic initialization whenever possible.

So what are very good reasons to use non-const global variables?

As a rule of thumb, any use of a global variable should meet at least the following two criteria: There should only ever be one of the thing the variable represents in your program, and its use should be ubiquitous throughout your program.

Protecting yourself from global destruction

If you do find a good use for a non-const global variable, a few useful bits of advice will minimize the amount of trouble you can get into. This advice isn’t only for non-const global variables, but can help with all global variables.

A joke

What’s the best naming prefix for a global variable?

Answer: //

C++ jokes are the best.

6.9 — Sharing global constants across multiple files (using inline variables)

Global constants as internal variables

Global constants as external variables

Given the above downsides, prefer defining your constants in a header file (either per the prior section, or per the next section). If you find that the values for your constants are changing a lot (e.g. because you are tuning the program) and this is leading to long compilation times, you can move just the offending constants into a .cpp file as needed.

Global constants as inline variables C++17

Best practice

If you need global constants and your compiler is C++17 capable, prefer defining inline constexpr global variables in a header file.

6.10 — Static local variables

Static local variables

Just like we use “g_” to prefix global variables, it’s common to use “s_” to prefix static (static duration) local variables.

Generating a unique ID number is very easy to do with a static duration local variable:

int generateID()
{
    static int s_itemID{ 0 };
    return s_itemID++; // makes copy of s_itemID, increments the real s_itemID, then returns the value in the copy
}

The first time this function is called, it returns 0. The second time, it returns 1. Each time it is called, it returns a number one higher than the previous time it was called. You can assign these numbers as unique IDs for your objects. Because s_itemID is a local variable, it can not be “tampered with” by other functions.

Best practice

Initialize your static local variables. Static local variables are only initialized the first time the code is executed, not on subsequent calls.

Don’t use static local variables to alter flow

Static local variables should only be used if in your entire program and in the foreseeable future of your program, the variable is unique and it wouldn’t make sense to reset the variable.

Best practice

Avoid static local variables unless the variable never needs to be reset.

6.11 — Scope, duration, and linkage summary

6.12 — Using declarations and using directives

Problems with using directives (a.k.a. why you should avoid “using namespace std;”)

In modern C++, using directives generally offer little benefit (saving some typing) compared to the risk. Because using directives import all of the names from a namespace (potentially including lots of names you’ll never use), the possibility for naming collisions to occur increases significantly (especially if you import the std namespace).

Best practices for using statements

Best practice

Prefer explicit namespaces over using statements. Avoid using directives whenever possible. using declarations are okay to use inside blocks.

6.13 — Inline functions

Inline expansion

Fortunately, the C++ compiler has a trick that it can use to avoid such overhead cost: Inline expansion is a process where a function call is replaced by the code from the called function’s definition.

When inline expansion occurs

Every function falls into one of three categories, where calls to the function:

Must be expanded.
May be expanded (most functions are in this category).
Can’t be expanded.
A function that is eligible to have its function calls expanded is called an inline function.

The inline keyword, historically

Best practice

Do not use the inline keyword to request inline expansion for your functions.

The inline keyword, modernly

Best practice

Avoid the use of the inline keyword for functions unless you have a specific, compelling reason to do so.

6.14 — Constexpr and consteval functions

Constexpr functions can be evaluated at compile-time

A constexpr function is a function whose return value may be computed at compile-time. To make a function a constexpr function, we simply use the constexpr keyword in front of the return type. Here’s a similar program to the one above, using a constexpr function:

#include <iostream>

constexpr int greater(int x, int y) // now a constexpr function
{
    return (x > y ? x : y);
}

int main()
{
    constexpr int x{ 5 };
    constexpr int y{ 6 };

    // We'll explain why we use variable g here later in the lesson
    constexpr int g { greater(x, y) }; // will be evaluated at compile-time

    std::cout << g << " is greater!\n";

    return 0;
}

Best practice

Use a constexpr return type for functions that need to return a compile-time constant.

Constexpr functions are implicitly inline

Constexpr functions can also be evaluated at runtime

Key insight

Allowing functions with a constexpr return type to be evaluated at either compile-time or runtime was allowed so that a single function can serve both cases.

Otherwise, you’d need to have separate functions (a function with a constexpr return type, and a function with a non-constexpr return type). This would not only require duplicate code, the two functions would also need to have different names!

So when is a constexpr function evaluated at compile-time?

Key insight

A constexpr function that is eligible to be evaluated at compile-time will only be evaluated at compile-time if the return value is used where a constant expression is required. Otherwise, compile-time evaluation is not guaranteed.

Thus, a constexpr function is better thought of as “can be used in a constant expression”, not “will be evaluated at compile-time”.

Determining if a constexpr function call is evaluating at compile-time or runtime

Prior to C++20, there are no standard language tools available to do this.

In C++20, std::is_constant_evaluated() (defined in the <type_traits> header) returns a bool indicating whether the current function call is executing in a constant context. This can be combined with a conditional statement to allow a function to behave differently when evaluated at compile-time vs runtime.

#include <type_traits> // for std::is_constant_evaluated
constexpr int someFunction()
{
    if (std::is_constant_evaluated()) // if compile-time evaluation
        // do something
    else // runtime evaluation
        // do something else
}

Used cleverly, you can have your function produce some observable difference (such as returning a special value) when evaluated at compile-time, and then infer how it evaluated from that result.

Forcing a constexpr function to be evaluated at compile-time

Consteval

C++20 introduces the keyword consteval, which is used to indicate that a function must evaluate at compile-time, otherwise a compile error will result. Such functions are called immediate functions.

Just like constexpr functions, consteval functions are implicitly inline.

Best practice

Use consteval if you have a function that must run at compile-time for some reason (e.g. performance).

Using consteval to make constexpr execute at compile-time C++20

6.15 — Unnamed and inline namespaces

6.x — Chapter 6 summary and quiz

Inline functions were originally designed as a way to request that the compiler replace your function call with inline expansion of the function code. You should not need to use the inline keyword for this purpose because the compiler will generally determine this for you. In modern C++, the inline keyword is used to exempt a function from the one-definition rule, allowing its definition to be imported into multiple code files. Inline functions are typically defined in header files so they can be #included into any code files that needs them.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scope, Duration, and Linkage___CH_6 的相关文章

  • WindowsError:[错误 126] 使用 ctypes 加载操作系统时

    python代码无法在Windows 7平台上运行 def libSO lib ctypes cdll LoadLibrary ConsoleApplication2 so lib cfoo2 1 3 当我尝试运行它时 得到来自python
  • 如何在 VC++ CString 中验证有效的整数和浮点数

    有人可以告诉我一种有效的方法来验证 CString 对象中存在的数字是有效整数还是浮点数吗 Use tcstol http msdn microsoft com en us library w4z2wdyc aspx and tcstod
  • 在 HKCR 中创建新密钥有效,但不起作用

    我有以下代码 它返回 成功 但使用两种不同的工具使用搜索字符串 3BDAAC43 E734 11D5 93AF 00105A990292 搜索注册表不会产生任何结果 RegistryKey RK Registry ClassesRoot C
  • 使用 CMake 时如何导出 Emscripten 中的 C 函数

    In 本教程 https emscripten org docs porting connecting cpp and javascript Interacting with code html interacting with code
  • 如何在类文件中使用 Url.Action() ?

    如何在 MVC 项目的类文件中使用 Url Action Like namespace 3harf public class myFunction public static void CheckUserAdminPanelPermissi
  • 从复选框列表中选择循环生成的复选框中的一个复选框

    抱歉我的英语不好 在我的 ASP NET 网站上 我从 SQL 表导入软件列表 看起来像这样 但实际上要长得多 Microsoft Application Error Reporting br br Microsoft Applicatio
  • 有些有助于理解“产量”

    在我不断追求少吸的过程中 我试图理解 产量 的说法 但我不断遇到同样的错误 someMethod 的主体不能是迭代器块 因为 System Collections Generic List 不是迭代器接口类型 这是我被卡住的代码 forea
  • 如何将 .txt 文件中的数据转换为 xml? C#

    我在一个文本文件中有数千行数据 我想通过将其转换为更容易搜索的内容来轻松搜索 我希望 XML 或其他类型的大型数据结构 尽管我不确定它是否是最好的对于我的想法 每行的数据如下所示 第 31 册 托马斯 乔治 32 34 154 每本书都不是
  • 在 C# 中,如何根据在 gridview 行中单击的按钮引用特定产品记录

    我有一个显示产品网格视图的页面 该表内有一列 其中有一个名为 详细信息 的超链接 我想这样做 以便如果用户单击该特定产品的详细信息单元格 将打开一个新页面 提供有关该产品的更多信息 我不确定如何确定哪个Product记录链接的详细信息以及我
  • Eigen 和 OpenMP:由于错误共享和线程开销而没有并行化

    系统规格 Intel Xeon E7 v3 处理器 4 插槽 16 核 插槽 2 线程 核心 Eigen 系列和 C 的使用 以下是代码片段的串行实现 Eigen VectorXd get Row const int j const int
  • C++中判断unicode字符是全角还是半角

    我正在编写一个终端 控制台 应用程序 该应用程序应该包装任意 unicode 文本 终端通常使用等宽 固定宽度 字体 因此要换行文本 只需计算字符数并观察单词是否适合一行并采取相应的操作 问题是 Unicode 表中的全角字符在终端中占用了
  • 是否使用 C# 数据集? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我对 C 中的数据集概念有点困惑 编码 ASP NET 站点 但这并不重要 在我的阅读中 我了解到它们 本质上 用作我的应用程序和我的
  • 在 .NET MAUI 中实现 TouchTracking

    我一直致力于将我们的应用程序从 Xamarin Forms 迁移到 NET MAUI 我们的应用程序几乎没有绘图功能 用户可以用手指进行绘图 我们用了TouchTrackingXamarin Forms 中的 nuget 包 但与 NET
  • 如何递归取消引用指针(C++03)?

    我正在尝试在 C 中递归地取消引用指针 如果传递一个对象 那就是not一个指针 这包括智能指针 我只想返回对象本身 如果可能的话通过引用返回 我有这个代码 template
  • 不可变类与结构

    以下是类与 C 中的结构的唯一区别 如果我错了 请纠正我 类变量是引用 而结构变量是值 因此在赋值和参数传递中复制结构的整个值 类变量是存储在堆栈上的指针 指向堆上的内存 而结构变量作为值存储在堆上 假设我有一个不可变的结构 该结构的字段一
  • 在 C 中使用枚举而不是 #defines 作为编译时常量是否合理?

    在 C 工作了一段时间后 我将回到 C 开发领域 我已经意识到 在不必要的时候应该避免使用宏 以便让编译器在编译时为您做更多的工作 因此 对于常量值 在 C 中我将使用静态 const 变量或 C 11 枚举类来实现良好的作用域 在 C 中
  • 将二变量 std::function 转换为单变量 std::function

    我有一个函数 它获取两个值 x 和 y 并返回结果 std function lt double double double gt mult double x double y return x y 现在我想得到一个常量 y 的单变量函数
  • 将函数参数类型提取为参数包

    这是一个后续问题 解包 元组以调用匹配的函数指针 https stackoverflow com questions 7858817 unpacking a tuple to call a matching function pointer
  • 在 System.Type 上使用条件断点时出错

    这是函数 public void Init System Type Type this Type Type BuildFieldAttributes BuildDataColumns FieldAttributes 我在第一行设置了一个断点
  • 是否允许全局静态标识符以单个 _ 开头?

    换句话说 可能static 文件范围 全局变量恰好以一个下划线开头 而不会产生与 C 实现发生名称冲突的可能性 https www gnu org software libc manual html node Reserved Names

随机推荐

  • 运行ntpdate报错:Temporary failure in name resolution

    一 问题报错 忽然发现某台机器时间慢了些几分钟 之前没有搭建ntpd服务 目前都是使用的ntpdate加定时任务进行时间同步 直接执行ntpdate报错如下 ntpdate cn pool ntp org Exiting name serv
  • 大学四年,因为这8个网站,我成为同学眼中的学霸

    作者简介 CSDN top100 阿里云博客专家 华为云享专家 网络安全领域优质创作者 推荐专栏 对网络安全感兴趣的小伙伴可以关注专栏 网络安全入门到精通 大学期间 几乎每一个教过我的老师都反应 我的学习态度不好 我上课很少仔细听老师在讲什
  • DNF搭建服务器服务端搭建教程

    DNF搭建服务器服务端搭建教程 我是艾西 今天给大家分享下怎么样自己搭建一个DNF 前阵子体验了下其他GM搭建的服 那么对于自己搭建的好处在于出道即巅峰 想要什么武器就是一串代码命令的事情 下面我跟大家说一下需要准备那些东西 DNF服务端
  • java获取当前服务器系统默认得编码格式

    java文件中 可以通过下面方法获取执行这段代码的服务器系统的编码格式 System getProperty file encoding 输出的结果是String的字符串 例如 utf 8
  • Java之Spring

    目录 创建spring项目 存储bean对象到容器 spring 中 从spring中将bean取出 更简单的读取存储对象 存储bean对象 前置准备 添加注解存储 Bean 对象 获取bean对象 bean作用域和生命周期 定义 bean
  • QT信号和槽机制实现及源码阅读

    说明 QT的信号和槽采用观察者模式 Q OBJECT是提供信号和槽的基础 使用过connect第五个参数的可知 槽可以在信号发出的线程处理 也可以加入任务队列进行处理 但是在此只写了在触发线程处理的代码 如下是实现的类QT信号和槽 gt F
  • 终于有人把软件测试用例讲清楚了(一定要收藏)

    目录 1 公司流程 1 1 测试用例的4个特性 1 1 测试用例通常包括以下几个组成元素 1 编写测试用例的基本方法 1 1 1 概念 1 1 1 示例 1 1练习案例 1 1 边界值法 1 1 1 确定边界值的方法 1 1 因果图法 1
  • ubuntu 20.04装nvidia显卡驱动

    装这个显卡驱动遇到了很多问题 第一次装了两三天没有成功 休息了一个星期 又来试 终于成功了 显卡驱动安装 1 检查自己的显卡型号 lspci grep i vga 会出现一个16进制的数字 选有nvidia的那个就是独显 我的是TU104M
  • visual studio:解决方案资源管理器中限定为此范围的显示与取消

    参考 VS 解决方案资源管理器中限定为此范围的显示与取消
  • 利用python做一个超简单的抽签器

    抽签器 用python写一个超基础的简单版抽签器 我利用了list函数来存储待抽签的选项 先将候选人输入到列表中 再进行随机抽签 以下是代码 一个抽签器 能够从多人中随机抽取一人 import random def random draw
  • Seekbar细节

    Seekbar可以自定义thumb图标 但是有时候发现thumb没有展示完全 或者图标周围显示的是背景色 此时就需要设置一些属性 android background null android thumbOffset 0dp android
  • QT入门之QToolBar

    目录 一 QToolBar界面相关 1 布局介绍 2 界面基本属性 3 添加动作测试 4 代码添加动作 5 创建按钮 此文为作者原创 转载请标明出处 一 QToolBar界面相关 1 布局介绍 先看下界面中创建个toolBar 右键Main
  • 真题详解(传引用)-软件设计(七十五)

    真题详解 补码转换 软件设计 七十四 https blog csdn net ke1ying article details 130674214 分治算法技术设计 答案 1 问题划分 2 递归求解 3 合并解 虚拟存储体系 两级构成 解析
  • 3、RH850端口说明及及复用功能配置

    RH850端口有3种工作模式 通用IO口 普通数字口 PMC控制寄存器对应bit为0 软件配置复用模式 PMC控制寄存器对应bit为1 PIPC寄存器对应bit为0 硬件直接连接模式 PMC控制寄存器对应bit为1 PIPC寄存器对应bit
  • 冒号 定义成员函数_C++ 类成员 类成员的构造 冒号语法

    设有类CTime和CDate分别用于描述时间和日期 另外有CDateTime类描日期和时间 请为三个类给出具体的实现代码 并在main函数中测试 include includeusingnamespace 设有类CTime 和CDate分别
  • XMind 2020 for mac (XMind思维导图)

    xmind 2020中文版是一款十分实用的思维导图软件 相信很多用户都还不了解XMind XMind官方版优化了许多功能 性能上大大提高 使用XMind思维导图可以帮助用户完成逻辑图 树形图 组织结构图等 还可以导出ppt word 图片
  • 【java基础】 方法,实参和形参,方法的重载,签名,递归

    目录 方法概念及使用 实参和形参的关系 重要 方法的重载 方法签名 简单了解 递归 简单介绍 方法概念及使用 方法就是一个代码片段 类似于 C 语言中的 函数 作用 是能够模块化的组织代码 当代码规模比较复杂的时候 做到代码被重复使用 一份
  • element ui表单中嵌套时间和日期下拉选择并且提交给后端

    使用element ui 的
  • vue 中 ‘\“ 替换成 “/“

    var filePath trim filePath val 正则表达式替换字符 对于String对象的replace方法 表达式不加入g 则只替换第一个匹配 如果加入g 则替换所有匹配 var newFilPath filePath re
  • Scope, Duration, and Linkage___CH_6

    Each project corresponds to one program 6 1 Compound statements blocks A compound statement also called a block or block