c++中静态函数与动态函数的区别

2024-09-06 08:18
文章标签 动态 c++ 函数 区别 静态

本文主要是介绍c++中静态函数与动态函数的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在C语言中,由于没有类的概念,所以没有静态成员一说,在c中static的作用主要有2个:

一是隐藏功能,对于static修饰的函数和全局变量而言
二是保持持久性功能,对于static修饰的局部变量而言。
并且,因为存放在静态区,全局和局部的static修饰的变量,都默认初始化为0。

C语言中使用静态函数的好处:
      静态函数会被自动分配在一个一直使用的存储区,直到退出应用程序实例,避免了调用函数时压栈出栈,速度快很多。 
      关键字“static”,译成中文就是“静态的”,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。 使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。 
c语言中static的语义1.static变量:1).局部a.静态局部变量在函数内定义,生存期为整个源程序,但作用域与自动变量相同,只能在定义该变量的函数内使用。退出该函数后, 尽管该变量还继续存在,但不能使用它。b.对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。2).全局全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。但是他们的作用域,非静态全局 变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。2.static函数(也叫内部函数)只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。区别于一般的非静态函数(外部函数)     static在c里面可以用来修饰变量,也可以用来修饰函数。         先看用来修饰变量的时候。变量在c里面可分为存在全局数据区、栈和堆里。其实我们平时所说的堆栈是栈而不包含对,不要弄混。

在c++中,由于面向对象的思维,它与C语言中的作用有一些不同,有了类中静态成员的说法。静态成员不属于对象,而属于类。不创建对象也可调用。从代码形式上来说没有任何区别。普通类成员函数与静态成员函数的区别在于普通成员函数有一个隐藏的调用参数(this)指针。所以就是说静态成员函数没有对象也可调用。但他们都是在编译期就进行地址绑定的。虚拟成员函数与他们的区别在于虚拟函数是对象生成时有对象的虚表决定的(所以是动态的)。


对类的静态和非静态函数的不同的调用要求决定了它们在使用上的方便程度:非静态成员函数要通过对象调用,所以要求首先建立一个对象;而静态成员函数可不建立对象就可以被使用。因此,与类的非静态数据成员无关的成员函数,虽然可以被定义为非静态函数,但是如果定义为静态函数的话在使用上会更加方便。
另外,如果类的成员函数想作为回调函数来使用,一般情况下只能将它定义为静态成员才行。

C++类中的静态成员有一个非常好的功能,那就是无论类定义了多少个对象,这些对象始终都共同使用这一个静态成员


例如:  class A{ 

 static int num;

A(){num++}     } 

int A::num=0; 

 就会有如下效果:  A  a,b,c,d;     cout<<a.num<<","<<b.num<<","<<c.num<<","<<d.num    输出 4,4,4,4

可以看出,在每个对象中的num成员都只有一个副本。在内存中也是如此,初始化abcd时并没有分配新的内存。

在使用静态成员的过程中还有以下几点注意:

1.num不可以在类中初始化,更不可以在构造函数或构造函数初始化表中初始化。必须在类外初始化。方法是:

int A::num=0;    此时不能有对象被定义,也就是说县定义num才可以,定义a b等

2.如果num为public成员,那么任何时候都可以这样调用它 A::num  当然 a.num也可以


对于静态成员函数,它的特点和静态数据成员相似但也有不同:

class A{ 
int num; 
A(){num++}   

static int p(){return num;  }      }//wrong 


1.可以在类中定义。这一点与静态数据成员不同

2.若p()为public成员,则可以这样调用A::p()。这一点与静态数据成员相同。

3.静态成员函数不属于任何一个特定的对象,所以不存在隐含的this指针。如果要在函数中访问某个特定的对象的成员,必须结合使用操作符“.”或“->”来显示地制定所属对象。


4上面所给的程序是错误的因为num不属于所有的对象。如果num是静态的则可以。


静态成员函数常用来操作静态数据成员。

阅读扩充:c++中类的静态成员和静态函数

这篇关于c++中静态函数与动态函数的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1141485

相关文章

Mybatis的mapper文件中#和$的区别示例解析

《Mybatis的mapper文件中#和$的区别示例解析》MyBatis的mapper文件中,#{}和${}是两种参数占位符,核心差异在于参数解析方式、SQL注入风险、适用场景,以下从底层原理、使用场... 目录MyBATis 中 mapper 文件里 #{} 与 ${} 的核心区别一、核心区别对比表二、底

Python容器转换与共有函数举例详解

《Python容器转换与共有函数举例详解》Python容器是Python编程语言中非常基础且重要的概念,它们提供了数据的存储和组织方式,下面:本文主要介绍Python容器转换与共有函数的相关资料,... 目录python容器转换与共有函数详解一、容器类型概览二、容器类型转换1. 基本容器转换2. 高级转换示

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav

C# Semaphore与SemaphoreSlim区别小结

《C#Semaphore与SemaphoreSlim区别小结》本文主要介绍了C#Semaphore与SemaphoreSlim区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录一、核心区别概览二、详细对比说明1.跨进程支持2.异步支持(关键区别!)3.性能差异4.API 差

C++打印 vector的几种方法小结

《C++打印vector的几种方法小结》本文介绍了C++中遍历vector的几种方法,包括使用迭代器、auto关键字、typedef、计数器以及C++11引入的范围基础循环,具有一定的参考价值,感兴... 目录1. 使用迭代器2. 使用 auto (C++11) / typedef / type alias