Getter & Setter 在 C++/C 项目中?
Getter & Setter in C++/C project?
我正在尝试更新 C/C++ 代码,想使用 getter 和 setter 进行跟踪 and/or 测试。
为一般声明制作了一个模板class
#include <iostream>
using namespace std;
#define TRACK_PROP(a,b) TrackProp<a> b(#b);
#define TRACK_PROP_SET(a,b,c) TrackProp<a> b(#b, c);
template <class T>
class TrackProp {
public:
T _content;
const char* Name;
TrackProp(const char* name) { Name = name; }
TrackProp(const char* name, T val) { Name = name; _content = val; }
T operator =(T right)
{
if (_content != right) {
cout << Name << ":" << _content << "->" << right << endl;
_content = right;
}
return _content;
}
operator T() const
{
return _content;
}
T operator ++()
{
operator = (_content + 1);
return _content;
}
T operator ++(int)
{
operator = (_content + 1);
return _content - 1;
}
T operator --()
{
operator = (_content - 1);
return _content;
}
T operator --(int)
{
operator = (_content - 1);
return _content + 1;
}
T operator +=(int right)
{
operator = (_content + right);
return _content;
}
T operator -=(int right)
{
operator = (_content - right);
return _content;
}
};
我现在可以轻松翻译声明了
int foo;
int bar = 2;
// These 2 or even some object can be declared by
TRACK_PROP(int, foo);
TRACK_PROP_SET(int, bar, 2);
foo = 1; // = operator /setter
int baz;
baz = bar; // () operator /getter
但是在 C 文件中使用它们时也会出现问题。
您将如何更改它以保留 Get/Set/Name 功能并能够像在 C++ 中一样简单地在 C 文件中使用它?
C 没有运算符重载,C 运算符不是有效的宏名称,因此无法自动将任何 C 运算转换为函数调用。您当然可以实现 getter 和 setter(作为顶级函数,因为 C 也没有方法/成员函数),但它们需要显式声明和显式调用。
据我了解您想要实现的目标,那么,它在 C 中根本 行不通。您需要手动检测您的 C 源代码才能获得类似于你的模板在那边给你的东西。
附录
对于在同一个项目中同时拥有 C 和 C++ 代码的意义,似乎有些混淆。特别是,似乎有人认为它 具有 意义。它不适用,至少 none 适用于该问题。
C 源文件由 C 编译器编译,并定义了这些翻译单元可用的语言功能。 C++ 源由 C++ 编译器编译,并定义了 those 翻译单元中可用的语言功能。一侧的函数可以调用另一侧的函数,但有一些注意事项,但这并不依赖于属于同一个项目。它不足以让您的自动 getter/setter 技巧应用于 C 代码。
我不是专家,但是生成 C++/C 函数并用一些宏替换您的变量会不会太复杂了?
您稍作修改的版本:
#ifdef __cplusplus
#define TRACK_C(a, b) \
extern "C" a _get$##b() { \
return b; \
}; \
extern "C" void _set$##b(a c) { \
##b = c; \
};
#define TRACK_PROP(a,b) TrackProp<a> b(#b); \
TRACK_C(a, b)
#define TRACK_PROP_SET(a,b,c) TrackProp<a> b(#b, c); \
TRACK_C(a, b)
template <class T>
class TrackProp {
public:
T _content;
const char* Name;
TrackProp(const char* name) { Name = name; }
TrackProp(const char* name, T val) { Name = name; _content = val; }
T operator =(T right)
{
if (_content != right) {
cout << Name << ":" << _content << "->" << right << endl;
_content = right;
}
return _content;
}
operator T() const
{
return _content;
}
};
#else
#define TRACK_C(a,b) \
a _get$##b(); \
void _set$##b(a);
#define TRACK_GET(b) _get$##b()
#define TRACK_SET(b,c) _set$##b(c)
#endif
在 C++ 中,您仍然可以使用运算符
#include <iostream>
#include "TRACK_PROP.h"
using namespace std;
TRACK_PROP(int, demo);
extern "C" void test();
void main(void) {
demo = 123;
cout << demo;
test();
}
并在 C 中替换我的宏使用的演示变量:
#include "TRACK_PROP.h"
TRACK_C(int, demo)
void test() {
// demo = 1
TRACK_SET(demo, 1);
// demo = 3*demo;
TRACK_SET(demo, 3*TRACK_GET(demo)));
}
如果有更简单的选择就好了,但我也不知道有什么直接的方法...
我正在尝试更新 C/C++ 代码,想使用 getter 和 setter 进行跟踪 and/or 测试。
为一般声明制作了一个模板class
#include <iostream>
using namespace std;
#define TRACK_PROP(a,b) TrackProp<a> b(#b);
#define TRACK_PROP_SET(a,b,c) TrackProp<a> b(#b, c);
template <class T>
class TrackProp {
public:
T _content;
const char* Name;
TrackProp(const char* name) { Name = name; }
TrackProp(const char* name, T val) { Name = name; _content = val; }
T operator =(T right)
{
if (_content != right) {
cout << Name << ":" << _content << "->" << right << endl;
_content = right;
}
return _content;
}
operator T() const
{
return _content;
}
T operator ++()
{
operator = (_content + 1);
return _content;
}
T operator ++(int)
{
operator = (_content + 1);
return _content - 1;
}
T operator --()
{
operator = (_content - 1);
return _content;
}
T operator --(int)
{
operator = (_content - 1);
return _content + 1;
}
T operator +=(int right)
{
operator = (_content + right);
return _content;
}
T operator -=(int right)
{
operator = (_content - right);
return _content;
}
};
我现在可以轻松翻译声明了
int foo;
int bar = 2;
// These 2 or even some object can be declared by
TRACK_PROP(int, foo);
TRACK_PROP_SET(int, bar, 2);
foo = 1; // = operator /setter
int baz;
baz = bar; // () operator /getter
但是在 C 文件中使用它们时也会出现问题。
您将如何更改它以保留 Get/Set/Name 功能并能够像在 C++ 中一样简单地在 C 文件中使用它?
C 没有运算符重载,C 运算符不是有效的宏名称,因此无法自动将任何 C 运算转换为函数调用。您当然可以实现 getter 和 setter(作为顶级函数,因为 C 也没有方法/成员函数),但它们需要显式声明和显式调用。
据我了解您想要实现的目标,那么,它在 C 中根本 行不通。您需要手动检测您的 C 源代码才能获得类似于你的模板在那边给你的东西。
附录
对于在同一个项目中同时拥有 C 和 C++ 代码的意义,似乎有些混淆。特别是,似乎有人认为它 具有 意义。它不适用,至少 none 适用于该问题。
C 源文件由 C 编译器编译,并定义了这些翻译单元可用的语言功能。 C++ 源由 C++ 编译器编译,并定义了 those 翻译单元中可用的语言功能。一侧的函数可以调用另一侧的函数,但有一些注意事项,但这并不依赖于属于同一个项目。它不足以让您的自动 getter/setter 技巧应用于 C 代码。
我不是专家,但是生成 C++/C 函数并用一些宏替换您的变量会不会太复杂了? 您稍作修改的版本:
#ifdef __cplusplus
#define TRACK_C(a, b) \
extern "C" a _get$##b() { \
return b; \
}; \
extern "C" void _set$##b(a c) { \
##b = c; \
};
#define TRACK_PROP(a,b) TrackProp<a> b(#b); \
TRACK_C(a, b)
#define TRACK_PROP_SET(a,b,c) TrackProp<a> b(#b, c); \
TRACK_C(a, b)
template <class T>
class TrackProp {
public:
T _content;
const char* Name;
TrackProp(const char* name) { Name = name; }
TrackProp(const char* name, T val) { Name = name; _content = val; }
T operator =(T right)
{
if (_content != right) {
cout << Name << ":" << _content << "->" << right << endl;
_content = right;
}
return _content;
}
operator T() const
{
return _content;
}
};
#else
#define TRACK_C(a,b) \
a _get$##b(); \
void _set$##b(a);
#define TRACK_GET(b) _get$##b()
#define TRACK_SET(b,c) _set$##b(c)
#endif
在 C++ 中,您仍然可以使用运算符
#include <iostream>
#include "TRACK_PROP.h"
using namespace std;
TRACK_PROP(int, demo);
extern "C" void test();
void main(void) {
demo = 123;
cout << demo;
test();
}
并在 C 中替换我的宏使用的演示变量:
#include "TRACK_PROP.h"
TRACK_C(int, demo)
void test() {
// demo = 1
TRACK_SET(demo, 1);
// demo = 3*demo;
TRACK_SET(demo, 3*TRACK_GET(demo)));
}
如果有更简单的选择就好了,但我也不知道有什么直接的方法...