我最近一直在考虑这个问题。我们大多数人都清楚地意识到,在C
中,为了创建结构,通常在其前面加上typedef
,以避免在引用对象之前调用struct
关键字。当然,C仅限于结构而不是类。为了弥补这一点,C倾向于使用专用于结构的全局函数来创建面向对象的方法
例如:
typedef struct{
int foo;
float bar;
char* baz;
} SomeStruct;
Vs以上。
struct AnotherStruct {
int foo;
float bar;
char* baz;
};
当在函数中声明该类型的对象时, AnotherStruct
必须在其前面具有前缀关键字struct
。例如:
int main( ... )
{
struct AnotherStruct obj1; //correct
SomeStruct obj2; //correct
struct SomeStruct obj3; //bad
AnotherStruct obj4; //bad
}
在面向对象的方法方面:
typedef struct {
//member variables here
} SomeStruct;
SomeStruct* SomeStruct_New( int a, int b, int c )
{
SomeStruct* obj = calloc( sizeof( SomeStruct ), 1 ); //not sure if that's correct -- been a while since I've used calloc.
obj.a = a;
obj.b = b;
obj.c = c;
return obj;
}
void SomeStruct_Free( SomeStruct* free )
{
free( free );
}
这些函数很容易在没有包装器的情况下实现 - 我只是为了举例而使用它们。我的观点是,鉴于您已经可以在C ++中创建一个结构,它不需要typedef
在没有struct
关键字的情况下声明,并且使用与这些结构相关的非封装函数面向方法,我很想知道在C ++中C编码方法是否有任何优势,包括使用静态全局函数作为私有成员函数,以及将返回指向对象的指针的全局函数构造函数。
这主要是出于好奇,因为有时我觉得采取C方法只是为了接受它,但这可能只是一个优先事项。
答案 0 :(得分:3)
很难理解问题的要点。在我看来,你的主要讯问是:
优于
在某些情况下。
不。相当于。
除了异常(!)之外,您在C ++中表达的任何代码都可以用C表示。这只是语法糖的问题,使C ++对应物更容易阅读。 在反对者加入潮流之前,可以用C模拟虚拟表格。
不过,我宁愿使用C ++。编译器检查封装(private
),编译器驱动的重载选择,编译器 - 样板(模板)。它只是 语法糖,但是这种甜糖。
话虽如此:
class Foo {
Foo() {}
friend Foo build(int a, int b);
friend int getA(Foo const& foo);
friend int getB(Foo const& foo);
int a;
int b;
};
可以被认为是面向对象。
编辑:simple and dummy example of polymorphism。
#include <stdio.h>
// Interface
typedef void (*FunctionPrint)(void const*);
typedef struct {
FunctionPrint print;
} PrinterInterface;
void print(void const* item, PrinterInterface const* pi) {
(*pi->print)(item);
}
// Foo
typedef struct { int a; } Foo;
void printFoo(void const* arg) {
Foo const* foo = (Foo const*)arg;
printf("Foo{%d}\n", foo->a);
}
PrinterInterface const FooPI = { &printFoo };
// Bar
typedef struct { char* a; } Bar;
void printBar(void const* arg) {
Bar const* bar = (Bar const*)arg;
printf("Bar{\"%s\"}\n", bar->a);
}
PrinterInterface const BarPI = { &printBar };
// Main
int main() {
Foo foo = { 1 };
Bar bar = { "Hello, World!" };
print(&foo, &FooPI);
print(&bar, &BarPI);
}
结果:
Foo{1}
Bar{"Hello, World!"}
答案 1 :(得分:0)
据我所知,这种声明的存在只是因为一些常见的标题(主要来自OS API:想到windows.h或“xlib.h”)必须在C和C ++程序中使用,不可预知的C和C ++版本。
如果今天重写这样的API(注意:API本身,而不仅仅是接口),它们可能没有那些类型的声明。 是一种“混蛋编码”,它使API开发人员确定内存映射(当结构绑定到硬件或外部二进制格式时很重要)和“魔术数字定义”,它们从不在不同语言的不同标题中重复。
答案 2 :(得分:0)
不,我认为在C ++中没有任何理由可行。
您希望使用C方法的最明显的情况是中断和线程回调函数。但是那些可以写成C ++中的私有静态成员,这是首选。
通常,在极少数情况下,甚至从C或C ++中的函数返回指针也是有意义的。您的示例不是很好的OO,您强制类的用户在不需要时使用动态分配。在C中编写OO代码时,通常会将分配留给调用者。
当您不希望调用任何构造函数时,我可以在实时嵌入式编程中提出一些案例,因此完全避免使用类,但在这种情况下,您可能根本不会使用C ++。
答案 3 :(得分:0)