在我的测试中,我被告知我需要找到一种在C
中实现以下类的方法class A
{
private:
int a,b;
public:
void func1();
int c,d;
protected:
int e,f;
void fun();
};
C编译器是否也支持访问说明符private,public和protected inside结构?
答案 0 :(得分:8)
C中没有类,只有结构。 C ++中有类。
也没有private
:
struct A
{
int a, b;
int c, d;
int e, f;
};
void func1( struct A* );
void fun( struct A* );
但一切都是公开的。
为了使事情更加封装,您可以隐藏struct A的实际实现细节,并使用公共方法显示前向声明。
由于没有继承, protected
没有任何意义。您可以通过将您的详细信息或其功能暴露给某些内部模块来实现“友谊”,但友谊与受保护不同,这在C中根本不存在。
在你的课堂上,你已经公开了两个成员,但如果我们“隐藏”结构A,我们就会隐藏所有内容,所以请提供getter和setter。
或者我们可以“隐藏”我们结构的一部分,例如: struct A1;
struct A
{
struct A1 * privatePart;
int b, c; // public part
};
虽然它变得“混乱”,因为你必须开始分配私有部分(并记住在C中没有智能指针或析构函数,因此你必须更加小心内存管理)。
许多C API使用的是一个命名约定,它将“私有”变量称为“保留”,通常是reserved1,reserved2等。编译器不会阻止你写入它们,但你显然是这样做的您自己承担风险,并且明确表示您不应该访问这些成员(直接复制或类似的除外)。
答案 1 :(得分:2)
这是你在C中进行私有封装的方法。这个概念被称为opaque类型,或者更正式,不完整的类型。
myclass.h
typedef struct myclass myclass;
myclass* myclass_construct (void);
void myclass_set_x (myclass* this, int x);
int myclass_get_x (const myclass* this);
void myclass_destruct (myclass* this);
myclass.c
#include "myclass.h"
struct myclass
{
int x; // this is a private variable
};
myclass* myclass_construct (void)
{
myclass* instance = malloc (sizeof(myclass));
if(instance == NULL) { /* error handling */ }
instance->x = 0;
return instance;
}
void myclass_set_x (myclass* this, int x)
{
this->x = x;
}
int myclass_get_x (const myclass* this)
{
return this->x;
}
void myclass_destruct (myclass* this)
{
free(this);
}
static myclass_private_member (something_t s)
{
// pure private function, do something internal here
}
的main.c
#include "myclass.h"
myclass* mc = myclass_construct();
...
答案 2 :(得分:1)
C中没有访问控制。否则,您可以通过自由函数逼近C ++类成员函数的某些功能:
struct A { int a, b, c, d, e, f; };
void A_func1(struct A * th) { /* use "th->a" etc. */ }
void A_fun(struct A * th) { /* ditto */ }
用法:
struct A a;
A_func1(&a);
A_fun(&a);
正如@CashCow所说,通过正确构建翻译单元,您可以获得相当多的实现和界面分离。例如:
mylib.h:(发货时)
struct A;
void A_func1(struct A *);
mylib_secret_impl.c:(仅发送二进制文件!)
#include "mylib.h"
struct A { int a, b, c, d, e, f; };
void A_fun(struct A * th) { /* ... */ }
void A_func1(struct A * th) { /* use A_fun(th) and members of *th */ }
答案 3 :(得分:1)
C不支持访问说明符,但您可以使用仅在实现文件中定义的匿名结构模拟其某些功能。
// foo.h
typedef struct Foo Foo;
Foo * FooAlloc(int bar);
void FooFree(Foo *);
// foo.c
struct Foo {
int bar;
};
Foo * FooAlloc(int bar){
Foo * f = malloc(sizeof(*f));
f->bar = bar;
return f;
}
void FooFree(Foo * f){free(f);}
struct Foo的bar
成员只能由foo.c中的函数访问。缺点是你不能在堆栈上创建一个Foo。类似地,您可以将定义放入单独的“foo_private.h”标头中,以模拟受保护的访问。
答案 4 :(得分:0)
在结构中,您可以编写函数指针来模拟C ++类...
答案 5 :(得分:0)
类是C ++概念,而不是C概念。但是,可以通过使用指针和PIMPL在C中实现一些OO设计功能。
以下是我在C中实现类的方法:
A.H
struct privateA;
struct A {
struct A_private* private;
int c,d;
};
extern void A_func1(struct A*);
extern struct A* A_new();
A.C
struct A_private {
int a,b;
int e,f;
};
static struct A_private* A_private_new() {
struct A_private_new* this = malloc(sizeof(struct A_private);
this->a = 0;
this->b = 0;
this->e = 0;
this->f = 0;
}
struct A* A_new() {
struct A* this = malloc(sizeof (struct A));
this->private = A_private_new();
this->c = 0;
this->d = 0;
}
void A_func1(struct A* this) { this->c = 12; }
static void A_fun(struct A* this) { this->d = 7; }
main.c中:
#include "A.h"
int main () {
struct A* a = A_new();
A_func1(a);
}
答案 6 :(得分:0)
即使没有语言支持,也有众所周知的方法可以在C中实现大部分功能。你不能手动做的一件事是区分私人和受保护的。
/* Foo.h */
struct Foo {
int c, d;
};
struct Foo* newFoo(); /* you can't create these on the stack */
void Foo_func1(struct Foo*);
诀窍就是隐藏调用者无法访问的内容。与使用完全不透明类型不同,我们可以选择直接公开公共成员而无需函数调用。
/* Foo.c */
struct Foo_private {
struct Foo pub;
int a, b;
int e, f; /* note I'm not distinguishing private */
};
struct Foo* newFoo()
{
struct Foo_private *f = malloc(sizeof(*f))
/* initialize */
return &f->pub;
}
struct Foo_private* cast(Foo *f)
{
/* can do cunning things with offsets for inheritance,
but this is the easy case */
return (Foo_private *)f;
}
void Foo_func1(Foo *f)
{
struct Foo_private *fp = cast(f);
/* access private members here */
}
答案 7 :(得分:0)
C中没有类,但是通过使用struct和functions,你可以在没有继承和多态的情况下完成基本过程。