C语言中实现C++静态类成员变量
2011-08-27 15:38
288 查看
学过C++的程序员,在写回C语言的时候,常常会无意之中,用C++面向对象的思想来设计自己的C语言程序。不得不说,这绝对是一种进步。对于思想而言,是没有语言界限的,只有适合与不适合,没有能与不能,只要想这样去做,并且这样做是有价值的,那么就算是不适合,也是同样可以想方设法做到的。
因为就计算机语言的最终目的来说,它们本来都是为了实现一定的操作,可能语法格式不同,但最终的效果却会是相同的。这就好比汉语和英语,可能两种语言在“吃饭”这种说法上会有所不同,但最终的目的却是相同的。而面对同样的操作需要,即使是不同的语言,它们也必然会有自己独特的方式来达到相同的目的。所以,在C++这样一种面向对象语言中,能够做到的,在C语言中,同样有自己的方式可以做到。而这也符合我所一直坚信的原理(我自认为是真理)——所有语言都有自己的方式来达到同样的目的,不存在一种语言能够实现其他语言所无法实现的功能,在计算机中,一切的实现方式没有能与不能,只有适合与不适合。
说回正题,在C++中,创建类的时候,有时候为了让基于相同类的所有类实例共用同一成员变量,我们会将这些成员变量定义为static的存储类型,然后在外部初始化,如:
class CTest {
private:
static int TestNum ;
public:
CTest () { }
~CTest () { }
}
int CTest :: TestNum = 0 ;
这样定义之后,所有类CTest的实例都将共用同一块TestNum变量的空间,而不会创建自己的TestNum变量空间。
而用C语言开发大型项目的时候,我们一般也会用到面向对象的设计思想,为的是让庞大的数据得到统一分类管理。这时,我们会用到C语言的结构体struct来对数据及操作方法进行分对象组织管理(大致方法在我之前写过的《C面向对象思想的领悟》中有提到),可是在C语言的结构体定义中是不允许为成员变量添加存储类型的修饰的(C++中可以,不过只能添加static)。
那么又如何,让基于该结构体的所有变量共用同一块成员变量的空间?
其实很简单,在C语言中,最强大的莫过于指针(个人观点),同样,这时候,指针依然能够解决问题。示例如下:
static int grobal = 100 ;
struct My {
int * const i ;
char c ;
float f ;
} ;
只要将结构体中需要进行静态处理的成员定义为相应的指针类型,然后在定义结构体变量的时候赋予该成员相同的内存地址即可。完整的测试用例如下:
#include <stdio.h>
static int grobal = 100 ;
struct My {
int * const i ;
char c ;
float f ;
} ;
void main (int argc, char **argv)
{
struct My Me2 = {&grobal}, Me1 = {&grobal} ;
*Me1.i = 2 ;
printf ("Me2.i:%d\nMe1.i:%d\n", *Me2.i, *Me1.i) ;
}
此处grobal也可不定义为static,但是为了达到多个变量共用同一块grobal变量空间的目的,grobal必须定义为static并且要与结构体变量的定义放在同一C文件中,对结构体类型的定义要放在头文件中,而对结构体成员的操作则要放在另一个C文件中,此时可以防止grobal被外部文件直接修改。
Demo:
File: My.h
#include <stdio.h>
typedef struct My My ;
struct My {
int * const i ;
char c ;
float f ;
} ;
File: My.c
#include "My.h"
static int grobal = 100 ;
extern My Me2 = {&grobal}, Me1 = {&grobal} ;
File: Test.c
#include "My.h"
extern My Me2, Me1;
void main (int argc, char **argv)
{
/*如果这样使用,则编译器会报错,因为指针为const,不能被修改
int Tgrobal1 = 4, Tgrobal2 = 10;
Me1.i = &Tgrobal1 ;
Me2.i = &Tgrlbal2 ;
printf ("Me2.i:%d\nMe1.i:%d\n", *Me2.i, *Me1.i) ;
*/
*Me1.i = 2 ;
printf ("Me2.i:%d\nMe1.i:%d\n", *Me2.i, *Me1.i) ;
}
对指针i添加const修饰可以防止指针的指向被修改,真正达到多个结构体变量共用同一块成员变量空间的效果。
————@Author CLinHF
因为就计算机语言的最终目的来说,它们本来都是为了实现一定的操作,可能语法格式不同,但最终的效果却会是相同的。这就好比汉语和英语,可能两种语言在“吃饭”这种说法上会有所不同,但最终的目的却是相同的。而面对同样的操作需要,即使是不同的语言,它们也必然会有自己独特的方式来达到相同的目的。所以,在C++这样一种面向对象语言中,能够做到的,在C语言中,同样有自己的方式可以做到。而这也符合我所一直坚信的原理(我自认为是真理)——所有语言都有自己的方式来达到同样的目的,不存在一种语言能够实现其他语言所无法实现的功能,在计算机中,一切的实现方式没有能与不能,只有适合与不适合。
说回正题,在C++中,创建类的时候,有时候为了让基于相同类的所有类实例共用同一成员变量,我们会将这些成员变量定义为static的存储类型,然后在外部初始化,如:
class CTest {
private:
static int TestNum ;
public:
CTest () { }
~CTest () { }
}
int CTest :: TestNum = 0 ;
这样定义之后,所有类CTest的实例都将共用同一块TestNum变量的空间,而不会创建自己的TestNum变量空间。
而用C语言开发大型项目的时候,我们一般也会用到面向对象的设计思想,为的是让庞大的数据得到统一分类管理。这时,我们会用到C语言的结构体struct来对数据及操作方法进行分对象组织管理(大致方法在我之前写过的《C面向对象思想的领悟》中有提到),可是在C语言的结构体定义中是不允许为成员变量添加存储类型的修饰的(C++中可以,不过只能添加static)。
那么又如何,让基于该结构体的所有变量共用同一块成员变量的空间?
其实很简单,在C语言中,最强大的莫过于指针(个人观点),同样,这时候,指针依然能够解决问题。示例如下:
static int grobal = 100 ;
struct My {
int * const i ;
char c ;
float f ;
} ;
只要将结构体中需要进行静态处理的成员定义为相应的指针类型,然后在定义结构体变量的时候赋予该成员相同的内存地址即可。完整的测试用例如下:
#include <stdio.h>
static int grobal = 100 ;
struct My {
int * const i ;
char c ;
float f ;
} ;
void main (int argc, char **argv)
{
struct My Me2 = {&grobal}, Me1 = {&grobal} ;
*Me1.i = 2 ;
printf ("Me2.i:%d\nMe1.i:%d\n", *Me2.i, *Me1.i) ;
}
此处grobal也可不定义为static,但是为了达到多个变量共用同一块grobal变量空间的目的,grobal必须定义为static并且要与结构体变量的定义放在同一C文件中,对结构体类型的定义要放在头文件中,而对结构体成员的操作则要放在另一个C文件中,此时可以防止grobal被外部文件直接修改。
Demo:
File: My.h
#include <stdio.h>
typedef struct My My ;
struct My {
int * const i ;
char c ;
float f ;
} ;
File: My.c
#include "My.h"
static int grobal = 100 ;
extern My Me2 = {&grobal}, Me1 = {&grobal} ;
File: Test.c
#include "My.h"
extern My Me2, Me1;
void main (int argc, char **argv)
{
/*如果这样使用,则编译器会报错,因为指针为const,不能被修改
int Tgrobal1 = 4, Tgrobal2 = 10;
Me1.i = &Tgrobal1 ;
Me2.i = &Tgrlbal2 ;
printf ("Me2.i:%d\nMe1.i:%d\n", *Me2.i, *Me1.i) ;
*/
*Me1.i = 2 ;
printf ("Me2.i:%d\nMe1.i:%d\n", *Me2.i, *Me1.i) ;
}
对指针i添加const修饰可以防止指针的指向被修改,真正达到多个结构体变量共用同一块成员变量空间的效果。
————@Author CLinHF
相关文章推荐
- C++中的Thunk技术 / 非静态类成员函数作为回调函数 的实现方法
- 转:C语言中的static变量和C++静态数据成员(static member)
- C++面向对象—成员函数与成员变量的实现机制学习笔记(1)
- 第一周:C++实现一个不带指针成员变量的类【Boolean】
- C语言中的static变量和C++静态数据成员(static member)
- C++使用模版实现按成员变量或者成员函数排序
- C语言中的static变量和C++静态数据成员
- C语言中的static变量和C++静态数据成员(static member)
- C++复习第一天 静态类成员实现单例模式
- C语言中的static变量和C++静态数据成员 的访问情况
- C++利用类静态变量,实现伪类对象空指针成功访问含有成员变量的成员函数而不崩溃
- C++中的Thunk技术 / 非静态类成员函数作为回调函数 的实现方法
- 第二周:C++实现一个带指针成员变量的类【Boolean】
- C++global成员变量实现DllMain类似的调用
- C语言中的static变量和C++静态数据成员(static member)详解!
- C语言中的static变量和C++静态数据成员
- C++ 成员函数与成员变量的关系
- [C++备忘录]类成员变量初始化
- C++ 的一个问题的理解(私有变量成员)
- C++ 类中特殊的成员变量(常变量、引用、静态)的初始化方法