什么是一组漂亮的预处理器黑客(ANSI C89/ISO C90兼容),它在C中实现某种丑陋(但可用)的面向对象?
我熟悉一些不同的面向对象语言,所以请不要回答"学习C++!"这样的答案.我读过" 面向对象的ANSI C编程 "(当心:PDF格式)和其他一些有趣的解决方案,但我最感兴趣的是你:-)!
另请参见您能用C编写面向对象的代码吗?
我已经看到以下两种在C API中声明不透明类型的样式.使用一种风格而不是另一种风格有明显的优势吗?
// foo.h
typedef struct foo * fooRef;
void doStuff(fooRef f);
// foo.c
struct foo {
int x;
int y;
};
Run Code Online (Sandbox Code Playgroud)
// foo.h
typedef struct _foo foo;
void doStuff(foo *f);
// foo.c
struct _foo {
int x;
int y;
};
Run Code Online (Sandbox Code Playgroud) go version:1.13.4 在源码中sync/once.go,下面的注释提到了“热点路径”:
type Once struct {
// done indicates whether the action has been performed.
// It is first in the struct because it is used in the hot path.
// The hot path is inlined at every call site.
// Placing done first allows more compact instructions on some architectures (amd64/x86),
// and fewer instructions (to calculate offset) on other architectures.
done uint32
m Mutex
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
这里的“热路径”是什么意思?
“它是结构中的第一个”是否使“热路径”访问更有效?为什么?
可能重复:
我如何在C中模拟OO风格的多态?
我试图用我所知道的语言中的例子来更好地理解多态性的概念; C中有多态吗?
假设我们有一个包含不同元素的绘图程序,例如圆形,矩形,三角形等.不同种类的对象都需要类似的功能,比如draw()展示自己.
我想知道程序员如何处理现在通常通过多态解决的问题,即通过一组不相同的元素并调用不同对象的通用功能.
想到的一种方法是使用一个带有函数指针的结构,该函数指针指向适当的函数(或函数指针数组中的索引)以及指向实际实例的void指针,并将指针转换为正确的类型在功能中.但这就是我 - 一个对这个问题毫无头绪的人会这样做.
我确实意识到这可能是一个愚蠢的问题,但由于我在"过去"的日子里没有出现过,我真的很想知道这个问题是如何解决的.在程序编程中使用了什么样的方法并且它具有性能优势,因为我们都知道多态性即使在像C++这样的快速语言中也有开销,这是由于虚方法查找.
可能的重复:
如何在 C 中模拟 OO 风格的多态性?
我正在尝试使用联合在 C 中创建多态性。我执行以下操作。
typedef struct{
...
...
} A;
typedef struct{
...
...
} B;
typedef union{
A a;
B b;
}C;
Run Code Online (Sandbox Code Playgroud)
我的问题是:我怎么能有一个采用 C 类型但也允许 A 和 B 的方法。我希望以下内容起作用:
如果我定义一个函数:
myMethod(C){
...
}
Run Code Online (Sandbox Code Playgroud)
然后,我希望这个工作:
main(){
A myA;
myMethod(myA);
}
Run Code Online (Sandbox Code Playgroud)
它没有。有什么建议?
任何人都可以指点我如何使用ANSI C实现工厂模式?如果覆盖更多的模式,那将只是一个奖励.在C++中这样做对我来说是微不足道的,但由于C没有类和多态,我不太清楚如何做到这一点.我正在考虑使用所有常见数据类型的"基础"结构,然后使用void指针,并按照与顶部基础结构相同的顺序定义结构的所有公共部分?或者不能保证它们在内存中以相同的方式结束?
我使用嵌入式软件,遇到了(以及从这个模型中复制过的)我在大学时从未学过的界面(新毕业).它允许代码库在library function不知道library用它编译的内容的情况下进行调用,假设它们都具有相同的内容function.下面的例子只显示了一个radio1,但是假设有一个radio2,radio3等通过makefile.
在编译中,library我们执行以下操作.在.c源文件中,function声明和接口struct:
// function bodies that do things
void radio1_init_radio(void) {}
void radio1_calibrate_radio(void) {}
// populate global tune interface
const struct tune_if_t tune_if =
{
.init_radio = radio1_init_radio,
.calibrate_radio = radio1_calibrate_radio
}
Run Code Online (Sandbox Code Playgroud)
然后,在.h中我指定function pointers:
struct tune_if_t
{
void (*init_radio) (void);
void (*calibrate_radio) (void);
};
extern const struct tune_if_t tune_if;
Run Code Online (Sandbox Code Playgroud)
这允许库外的系统在function不知道编译和链接哪个无线电库的情况下调用:
int main( void )
{
// interface calls
tune_if.init_radio();
tune_if.calibrate_radio();
return …Run Code Online (Sandbox Code Playgroud) 假设定义了 2 个结构体,如下所示:
typedef struct {
T x;
T y;
} A;
typedef struct {
A a;
T z;
} B;
Run Code Online (Sandbox Code Playgroud)
我可以将指向结构 B 的指针视为指向结构 A 的指针吗?
实际上,这是可靠的/标准的/可移植的/编译器不变的:
B b = {{1,2},3};
A * a = &b;
print(a->x);
print(a->y);
Run Code Online (Sandbox Code Playgroud) 尝试在没有基类和虚拟调用的情况下获取编译时方法和对象选择.
情况如下:
struct A {
void f1()const { cout << "A::f1" << endl;}
void f2()const { cout << "A::f2" << endl;}
};
struct B {
void f1()const { cout << "B::f1" << endl;}
void f2()const { cout << "B::f2" << endl;}
};
class Holder {
A* _a = nullptr;
B* _b = nullptr;
public:
Holder(A* a): _a(a) {}
Holder(B* b): _b(b) {}
void f1()const {
if(_a) _a->f1();
else if(_b) _b->f1();
}
void f2()const {
if(_a) _a->f2();
else if(_b) _b->f2();
} …Run Code Online (Sandbox Code Playgroud)