在C++中,在头文件中可以有一个声明为内联的吸收器函数:
class Cpp_Example
{
public:
unsigned int get_value(void)
{ return value;}
private:
unsigned int value;
};
通过包含这个头文件,客户机方法和函数可以使用getter函数来访问私有变量。
我希望用C语言来模拟这个概念:你好。
#ifndef HELLO_H
#define HELLO_H
#include
inline void Print_Hello(void)
{
extern const char hello_text[32];
puts(hello_text);
}
inline void Print_Value(void)
{
extern unsigned int value;
printf("Value is: %d
", value);
}
#endif // HELLO_H
你好,C:
const char hello_text[32] ="Hello World!
";
static unsigned int value = 5U;
主要内容:
#include
#include
#include"hello.h"
int main(void)
{
Print_Hello();
Print_Value();
// puts(hello_text);
return EXIT_SUCCESS;
}
我从gcc得到一个链接器错误:
$ gcc -o main.exe main.c hello.c
/tmp/cc41ZB8H.o:main.c:(.rdata$.refptr.value[.refptr.value]+0x0): undefined reference to `value'
collect2: error: ld returned 1 exit status
有没有方法让内联函数(在头文件中)访问另一个翻译单元中的静态变量?
或者有实现内联getter函数的方法吗?
我在嵌入式平台上使用IAR嵌入式工作台、ARM7TDMI处理器。GCC编译器用于在PC上测试概念。
编辑1:背景我正在优化关键部分内的getter调用。目的是减少在关键部分花费的时间。
编辑2:无全局我们商店使用的编码准则没有规定全局变量。此外,该系统是一个运行微硅片的RTOS。
@chux:删除static会破坏封装和数据隐藏。变量变为任何人都可以访问的全局变量。
如果保持静止,就无法从外部访问它。记住,C中没有名称空间,第一个C编译器的链接器在一个符号中不支持超过6个字符(即变量名/函数名)。static关键字(在函数之外)被发明用来隐藏对象,以避免污染非常有限的全局名称空间。所以任何从外部访问对象的方法都是对的,这违背了静态的意图。
首先,与C++中有私有变量相同的方式,您可能意味着为EDCOX1 OR 2而不是全局变量拥有私有变量。有了这个假设,您可以使用一个模型:
/* some_type.h */
struct some_type
{
int public_data;
void *privates;
};
struct some_type_privates
{
char hello[32];
int value;
};
inline const char *get_hello(struct some_type *t)
{
struct some_type_privates *p = t->privates;
return p->hello;
}
inline int get_value(struct some_type *t)
{
struct some_type_privates *p = t->privates;
return p->value;
}
/* similarly for setters */
与您的私有变量及其getter和setter在头文件中的方式相同,您也可以在C中这样做。
另一方面,我建议不要在C中尝试编码C++,而C++喜欢使事情复杂化很多,以防止白痴破坏某些东西,而C则相信程序员有一定程度的智力。这些假设是否合理不是讨论的问题。但我要说的是,C的精神不是隐藏一个变量,这样程序员就不会错误地访问它。
也就是说,这是您通常在C中生成结构的方式:
struct some_type
{
int public_data;
char hello[32]; /* read only */
/* internal */
int value;
};
(当然,有足够的文档)它告诉任何程序员,她不应该重写hello,但可以自由地阅读(您试图通过内联getter实现的)。它还表明value是私有的,因此程序员不应该读或写它。
您可以在许多接受或返回结构的POSIX函数中看到这一点。一些不需要控制访问的允许您自由地修改结构,例如stat。一些确实需要检查输入的具有setter,例如pthread_attr_*。
您需要删除static关键字。static定义是编译单元的本地定义。
我想保持变量私有而不是全局的;类似C++类的概念。删除static关键字违反了这个概念。
然后将函数放在hello.c中并导出该函数。
然后它就不再在线了,所以打电话更贵。
下面是我用来隐藏全局变量的模式。
在一些头文件(如module_prefix.h中),您声明以下内容:
typedef int value_t; // Type of the variable
static inline value_t get_name(void) __attribute__((always_inline));
static inline void set_name(value_t) __attribute__((always_inline));
static inline value_t get_name(void) {
extern value_t module_prefix_name;
return module_prefix_name;
}
static inline void set_name(value_t new_value) {
extern value_t module_prefix_name;
module_prefix_name = new_value;
}
/* Note that module_prefix_name is *no longer* in scope here. */
当然,您必须在一些编译单元中定义module_prefix_name,而不使用static关键字,如上所述,例如在module_prefix.c中,您有以下内容:
#include"module_prefix.h"
value_t module_prefix_name = MODULE_PREFIX_NAME_INIT_VALUE;
这与Thomas Matthews试图使用的模式基本相同,深入了解其本质,并确保编译器始终在函数中输入,并且不会不必要地生成显式函数体。注意使用module_prefix作为穷人的姓名空间。
假设您的意思是全局的静态分配变量,您可以这样做:
例如:H:
#ifndef Example
#define Example
extern int getValue();
#endif
例如,C
#include"Example.h"
static int value;
inline int getValue() {
return value;
}
// All the functions in Example.c have read/write access
在用值例如.c
#include"Example.h"
// All the functions in UsesValueExample.c have read-only access
void printValue() {
printf("value = %d", getValue());
}
如果您想要花哨并强制所有代码通过getter和setter访问,例如,如果变量是易失性的,并且您希望大力鼓励所有方法使用变量的本地缓存以避免访问易失性的开销,那么:
例如,在挥发物中:
#ifndef VolatileExample
#define VolatileExample
extern int getValue();
#endif
在挥发物中例如.c
#include"VolatileExample.h"
void setValue(); // Forward declaration to give write access
// All the functions in VolatileExample.c have read/write access via getters and setters
void addToValuesAndIncrementValue(int const values[], int const numValues) {
int value = getValue(); // Cache a local copy for fast access
// Do stuff with value
for (int i = 0; i < numValues; i++) {
values[i] += value;
}
value++;
// Write the cache out if it has changed
setValue(value);
}
// Put the definitions after the other functions so that direct access is denied
static volatile int value;
inline int getValue() {
return value;
}
inline void setValue(int const newValue) {
value = newValue;
}
在用volatilevalueexample.c
#include"VolatileExample.h"
// All the functions in UsesVolatileValueExample.c have read-only access
void printValue() {
printf("value = %d", getValue());
}
我的理解是,在头文件中声明一个变量,特别是作为static声明,将在包含头文件的每个源文件中创建一个实例。
在C static中是如何进行私有静态分配变量的。我知道语法很奇怪,
失事张贴。在c static中,对于文件作用域变量来说,它已经是静态的,按照static的正常含义,是私有的。我知道这很奇怪,但就是这样!注意,我在.c实现文件中使用了static,而不是在声明头.h文件中,也不是在using.c文件中。
正如沙巴所写,它在C语言中并不真正起作用。关键字inline意味着静态的,即使编译器实际上没有将其inline。如果它是一个如此短的函数,它可能会内联它。但关键是,如果它不是静态的,它甚至不能考虑将它内联,因为函数需要在外部可见,它需要一个地址,而内联函数没有这个地址。因为它在您的编译单元中是本地的,所以它只能处理该编译单元内已知的内容。因此,你需要说一些关于这个值变量,就像你也需要在C++头中提到它一样,只有在C中没有私有的东西。你不能在同一种情况下进行数据隐藏和数据隐藏,既不在C中,也不在C++中。