c程序中面向对象的方法

时间:2016-04-04 05:18:50

标签: c oop

我在面向对象编程方面没有太多经验。我正在尝试在c中创建一个具有自己方法的对象。 我已经声明了具有指向函数的指针的结构。该变量的所有实例都将指向相同的函数。但是目前我需要在main(行1和行2)中初始化变量的每个实例。那么有什么方法可以在我声明时初始化它的默认值吗?

#include <stdio.h>
#include <stdlib.h>

typedef struct serialStr Serial;

struct serialStr
{
    void(*init)(Serial*);
    void(*open)();
    void(*close)();
};


void open()
{
    printf("Open Port Success\n");
    return;
}

void close()
{
    printf("Close port Success\n");
    return;
}


void init(Serial* ptr)
{
    ptr->open   = open;
    ptr->close  = close;
}

int main()
{
    Serial serial,serial_2;

    serial.init = init;         
    serial.init(&serial);       // Line1

    serial_2.init = init;       
    serial_2.init(&serial_2);  // Line2

    serial.open();
    //rest of code
    serial.close();

    serial_2.open();
    serial_2.close();
    return 0;

}

3 个答案:

答案 0 :(得分:3)

在C中,标准方法是声明初始化器宏:

#define SERIAL_INITIALIZER { .init = init, .open = open, /* and others */ }

Serial serial = SERIAL_INITIALIZER;

在C的大多数情况下,根本不需要动态初始化变量。您只需要malloc ed对象。

答案 1 :(得分:1)

C ++通过调用构造函数/析构函数来添加一些自动化。在纯C中是没有办法这样做的。你应该手动完成所有步骤:创建和初始化对象(为结构调用类似构造函数的函数),通过结构实例中的指针调用函数,调用析构函数(它应该销毁实例并释放相关资源)。

如果你的任务中没有多态,那么使用简单的方法 - 没有指向函数的指针,但是每个函数(方法)都应该指向对象。

常见案例:

struct MyStruct
{
    // data
};

struct MyStruct* createMyStruct(/* maybe some input */)
{
    // create, init and return the structure instance
}

void destoyMyStruct(struct MyStruct* obj)
{
    // free resources and delete the instance
}

void doSomeAction(struct MyStruct* obj /* , some other data */)
{
    // ...
}

int main()
{
    struct MyStruct* object = createMyStruct();
    doSomeAction(object);
    destoyMyStruct(object);
    return 0;
}

编辑1:宏仅适用于非常简单的情况和容易出错的方式。

答案 2 :(得分:0)

通常,您可以通过&#34; opaque类型&#34;来完成此操作。这意味着您在标题中声明了一个不完整类型的对象:

typedef struct Serial Serial;

然后在C文件中放置实际的struct定义。这会将结构的内容隐藏到调用者(私有封装)。然后,您可以从构造函数中设置私有成员函数:

struct Serial
{
    void(*init)(void);
    void(*open)(void);
    void(*close)(void);
};


// private member functions:
static void open (void);
...


// constructor:
Serial* SerialCreate (void)
{
  Serial* s = malloc(sizeof (*s));
  ...
  s->open = open;
  return s; 
}

这意味着如果您希望继承该类,则只需要更改构造函数。

当然,如果您希望实现真正的多态,那么您不想更改任何代码。您可以通过将init函数作为参数传递给构造函数来解决此问题。

头文件:

typedef void init_func_t (void);

c file:

// constructor:
Serial* SerialCreate (init_func_t* init)
{
  Serial* s = malloc(sizeof (*s));
  ...

  init();

  return s; 
}

然后从继承类的init函数中设置所有私有成员函数。