怎么在自己做的網(wǎng)站上發(fā)視頻引擎網(wǎng)站
本文參考:
- c語(yǔ)言面向?qū)ο笾庋b
- c面向?qū)ο笾^承
- Linux源碼分析之多態(tài)
一、封裝
封裝的本質(zhì)就是將數(shù)據(jù)和方法集中到一個(gè)對(duì)象中,c++或者java使用的是class來(lái)實(shí)現(xiàn)。c語(yǔ)言中可以使用struct來(lái)實(shí)現(xiàn)同樣的功能。比如下面的程序:
struct student
{int age;char *name;void (*read)(char *);
};void read_book(char *book)
{printf("book is :%s", book);
}int main(void)
{struct student s1;s1.age = 10;s1.name = strdup("xiaoming");s1.read = read_book;printf("name: %s age: %d\n", s1.name, s1.age);s1.read("math");free(s1.name)return 0;
}
二、繼承
繼承可以讓子類(lèi)使用父類(lèi)的資源,減少重復(fù)。父類(lèi)可以是將子類(lèi)的共同點(diǎn)抽象出來(lái),提升代碼層次。
如何使用c來(lái)實(shí)現(xiàn)同樣的效果,首先肯定還是需要struct來(lái)構(gòu)建父類(lèi)和子類(lèi),同時(shí)如果要達(dá)到is a的效果,從內(nèi)存空間來(lái)看,也就意味著父類(lèi)占據(jù)了子類(lèi)內(nèi)存地址的最開(kāi)始位置。所以,我們可以按照下面的方式來(lái)構(gòu)造繼承。
struct parent
{void (*func1)(void);
};struct child
{struct parent pt;void (*func2)(void);
};void test(struct parent *p)
{p->func1();
}int main()
{struct child cd;test((struct parent *)&cd);
}
三、多態(tài)
多態(tài)就是在程序運(yùn)行時(shí),父類(lèi)指針可以根據(jù)具體的子類(lèi)對(duì)象來(lái)執(zhí)行不同的函數(shù)行為。c++中一般通過(guò)虛函數(shù)來(lái)實(shí)現(xiàn)。c實(shí)現(xiàn)多態(tài)主要是通過(guò)結(jié)構(gòu)體和函數(shù)指針。
#include <stdio.h> // 定義基類(lèi)
struct Shape
{ void (*draw)(struct Shape*);
};// 定義派生類(lèi)
struct Circle
{ struct Shape shape; int radius;
};struct Rectangle
{ struct Shape shape; int width; int height;
};void drawCircle(struct Shape *shape)
{ printf("Drawing a circle...\n");struct Circle *circle = (struct Circle *)shape;printf("Circle radius is %d\n", circle->radius);
}void drawRectangle(struct Shape *shape)
{ printf("Drawing a rectangle...\n");struct Rectangle *rectangle = (struct Rectangle *)shape;printf("Rectangle width is %d\n", rectangle->width);printf("Rectangle height is %d\n", rectangle->height);
}int main()
{ struct Circle circle;circle.shape.draw = drawCircle;circle.radius = 10;struct Rectangle rectangle; rectangle.shape.draw = drawRectangle;rectangle.width = 10;rectangle.height = 20;struct Shape *shape;shape = (struct Shape *)&circle;shape->draw(shape);shape = (struct Shape *)&rectangle;shape->draw(shape);return 0;
}
在Linux內(nèi)核中數(shù)量最多的就是驅(qū)動(dòng)程序代碼,因?yàn)橛布O(shè)備是多種多樣的,每種設(shè)備都會(huì)有對(duì)應(yīng)的驅(qū)動(dòng)程序。Linux對(duì)上層的接口都是統(tǒng)一和抽象的,要保證相同的接口最終能夠?qū)?yīng)到特定的硬件設(shè)備,這就需要使用多態(tài)的技巧。
include/linux/i2c.h
這個(gè)結(jié)構(gòu)體定義了不少函數(shù)指針,就是實(shí)現(xiàn)多態(tài)的關(guān)鍵struct i2c_driver {unsigned int class;/* Standard driver model interfaces */int (*probe)(struct i2c_client *, const struct i2c_device_id *);int (*remove)(struct i2c_client *);/* New driver model interface to aid the seamless removal of the* current probe()'s, more commonly unused than used second parameter.*/int (*probe_new)(struct i2c_client *);/* driver model interfaces that don't relate to enumeration */void (*shutdown)(struct i2c_client *);/* Alert callback, for example for the SMBus alert protocol.* The format and meaning of the data value depends on the protocol.* For the SMBus alert protocol, there is a single bit of data passed* as the alert response's low bit ("event flag").* For the SMBus Host Notify protocol, the data corresponds to the* 16-bit payload data reported by the slave device acting as master.*/void (*alert)(struct i2c_client *, enum i2c_alert_protocol protocol,unsigned int data);/* a ioctl like command that can be used to perform specific functions* with the device.*/int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);struct device_driver driver;const struct i2c_device_id *id_table;/* Device detection callback for automatic device creation */int (*detect)(struct i2c_client *, struct i2c_board_info *);const unsigned short *address_list;struct list_head clients;bool disable_i2c_core_irq_mapping;
};
drivers/i2c/i2c-slave-eeprom.c