[LINUX] Betrachten Sie eine einfach zu verwendende objektorientierte "Like" -Darstellung in C. ~ Teil 2 Interface Override

0/2 Einführung ungültig * 1/2 Klassenrepräsentation und Vererbung 1/2 2018/07/01 Überdacht Überdacht: Klassenausdruck und Vererbung 2/2 Schnittstelle, Überschreiben ← Hier

Diesmal ist es eine Schnittstellenklasse und eine Überschreibung. Ehrlich gesagt, nach dem Schreiben von Realization of Interface Class Es gibt einen Teil, der zutiefst objektorientiert ist, weil ich meine Lieblingsgeschichte schreiben möchte, die diesmal beschrieben werden soll.

Das Konzept und die Implementierungsmethode der C-Sprache und der Schnittstellenklasse sind üblich! Es ist ein Eindruck.

** Was ist eine Schnittstellenklasse **

Definieren Sie nur die Methode und überlassen Sie die Implementierungsklasse jeder einzelnen. Es ist für den Benutzer praktisch, das Verhalten durch Auswahl der Implementierungsklasse zu ändern.

Grob in C-Sprache geschrieben,

Schnittstellenklasse ⇒ API-Definition der dynamischen Bibliothek Implementierungsklasse ⇒ Dynamischer Bibliothekskörper

nicht wahr. Der Unterschied ist, dass Sie mehr als eine haben können.

** Über die Nützlichkeit der Darstellung von Schnittstellenklassen in C-Sprache **

Als Realisierungsmethode [Darstellung der vorherigen öffentlichen Methode](https://qiita.com/developer-kikikaikai/items/ee782a4865d9186c5d8c#%E3%82%AF%E3%83%A9%E3%82%B9%E3 Geschrieben in% 82% 92% E3% 81% A9% E3% 81% 86% E8% A1% A8% E7% 8F% BE% E3% 81% 99% E3% 82% 8B% E3% 81% 8B) Ich werde es weglassen, Wie dort erwähnt ** Wenn Sie beim Aufrufen einer Klassenmethode in C this verwenden, müssen Sie diese als Argument übergeben ** Ich schrieb.

Wenn Sie dann darüber nachdenken, viele Implementierungsklassen für Schnittstellenklassen zu implementieren, Es ist ganz anders, ob die API als öffentliche API oder als Schnittstellenklasse mit einem Funktionszeiger ausgedrückt werden soll.

Lass es uns tun, weil es einfach mit der Interface-Klasse gemacht werden kann! Es ist jedoch eine Verschwendung, wenn es mit dem vorhandenen System identisch ist. Was für ein Fall ist dann effektiv?

** Fall 1: Wenn die Person, die die Schnittstelle tatsächlich verwendet, die Substanz überhaupt nicht kennen muss **

In einem System, in dem Module mit derselben Schnittstelle hinzugefügt oder entfernt werden, können Sie beispielsweise eine Verwaltungsklasse erstellen, ohne den Benutzer auf die Schnittstellenimplementierungsklasse aufmerksam zu machen. In einem solchen Fall ist es sinnvoll, eine Schnittstellenklasse in der Sprache C einzuführen. Das Beispiel in [Realisierung der Schnittstellenklasse](https://qiita.com/developer-kikikaikai/items/47f92acbc0a19172b6d4:'interface class ') ist so.

Der Interviewer erhält die Informationen der zu interviewenden Personen als Schnittstellenklasse und stellt nacheinander feste Fragen. Der Interviewer muss nur die Fragen beantworten, so dass es sich anfühlt, als würde er das Management der zu interviewenden Person einer anderen Person überlassen.

Organisieren und erklären Sie den Code. Definieren Sie zunächst eine Schnittstellenklasse mit dem Namen culture_if.

culture.h


struct culture_if {
        char *(*introduce)();//Vorstellen
        char *(*get_name)();//Name
        char *(*answer)(int id);//Frage
};

Definieren Sie als Nächstes eine öffentliche API mit dem Namen "people_manager".

people_manager.h


#include "culture_if"
void * people_manager_new();
int people_manager_get_any_people(void *, struct culture_if *peoples);
void * people_manager_free(void *);

"Neu" die "Culture_if" -Implementierungsklasse derer, die heute kamen, als "people_manager" neu war, Verwenden Sie people_manager_get_any_people, um die Liste zu übergeben.

Die Implementierung des Interviewers sieht also so aus.

main.c


#include <stdio.h>
#include "people_manager.h"
#include "culture_if"

int main() {
	struct {
		int id;
		char * question;
	} questions[] =
	{
		{FOOD, FOOD_QUESTION},
		{HAPPY, HAPPY_QUESTION},
		{CONPUTER, CONPUTER_QUESTION},
	};

	struct culture_if max_members[10];
	void * people_manager = people_manager_new();
	int member_num = people_manager_get_any_people(max_members);

	printf("[Interviewer]Hallo zusammen. Ich freue mich darauf, heute mit Ihnen zusammenzuarbeiten. Bitte stellen Sie sich zunächst kurz vor.\n");

	int i=0;
	for( i = 0 ; i < member_num; i ++ ) {
		printf("  [%Selbsteinführung der d-ten Person]\n", i+1);
		printf("\t%s\n", max_members[i].introduce() );
	}

	printf("\n");
	printf("[Interviewer]Vielen Dank. Dann möchte ich nacheinander Fragen stellen.\n Bitte zögern Sie nicht zu antworten.\n\n");

	int j=0;
	for ( i = 0 ; i < sizeof(questions)/sizeof(questions[0]); i ++ ) {
		printf("Q %d: %s\n", i+1, questions[i].question);
		for( j = 0 ; j < member_num ; j ++ ) {
			printf("  [A:%s]\n", max_members[i].get_name());
			printf("\t%s\n", max_members[i].answer(i));
		}
		printf("\n");
	}

	printf("[Interviewer]Damit ist die Frage abgeschlossen. Vielen Dank an alle!\n");
	people_manager_free(people_manager);
	return 0;
}

Selbst wenn sich die zu interviewende Person ändert, kann die Implementierung auf der Interviewerseite so beibehalten werden, wie sie ist. Ist diese Art der Nutzung nicht gut?

** Fall 2: Hinzufügen eines statischen Bibliotheks-Plug-Ins mit dlopen **

Ist es nur für Linux? Es gibt eine Standardfunktion namens dlopen / dlsym.

dlfcn.h


#include <dlfcn.h>
void *dlopen(const char *filename, int flag);
void *dlsym(void *handle, const char *symbol);

Auszug aus manpage.

Kurz gesagt, wenn Sie die Bibliotheksdatei mit dlopen angeben und dann den Funktionsnamen mit dlsym angeben, erhalten Sie den der Funktion entsprechenden Funktionszeiger. Danach kann die Funktion der Bibliothek mit dem Funktionszeiger ausgeführt werden. Es ist ein existierender Mechanismus, aber es ist genau die Idee einer Schnittstellenklasse.

Eigentlich ist es so, wie man es als Schnittstellenimplementierungsklasse verwendet

  1. Definieren Sie einen Funktionszeiger, der eine Schnittstellenklasse sein soll. Lass uns mit culture.h gehen.
  2. Bestimmen Sie den API-Namen für jede Methode der Schnittstellenklasse.
  3. Laden Sie die Bibliothek, die die obigen 3 APIs implementiert, mit dlopen und setzen Sie sie mit dlsym auf das entsprechende culture_if.

Entscheiden Sie beispielsweise den Namen wie folgt und bitten Sie die für die Schnittstellenimplementierung verantwortliche Person, jede API zu implementieren und zu einer Bibliothek zu machen. --void (* Introduce) () void culture_if_introduce ();// Selbsteinführung --char * (* get_name) ()void culture_if_get_name ();// Name --char * (* answer) (int id)void culture_if_answer ();// Frage

Wenn Sie können, laden Sie jede Bibliothek mit dlopen, und die Methoden der Schnittstellenimplementierungsklasse sind abgeschlossen.

python


struct culture_if * culture_if_new( chhar * lname /*"Name der Bibliotheksdatei"*/) {
    void * handle = dlopen(lname , flag);
    struct culture_if * culture_if = malloc(sizeof(struct culture_if ));

    culture_if->introduce = dlsym(handle, "culture_if_introduce");
    culture_if->get_name= dlsym(handle, "culture_if_get_name");
    culture_if->answer= dlsym(handle, "culture_if_answer");
    return culture_if;
}

Das Schöne daran ist, dass der Methodenname auf der Seite der Implementierungsklasse ebenfalls festgelegt werden kann und die Logik auf der Verwaltungsseite ebenfalls festgelegt wird. Wenn dies gut gemacht wurde, können Sie die Anzahl der Schnittstellenimplementierungsklassen erhöhen, ohne die Verwaltungsseite zu berühren. Vielleicht sieht das übliche OSS mit zusätzlichen Steckern so aus.

Ich bin absolut süchtig nach einem Designmuster, also denke ich, dass ich bald ein Muster machen werde.

** Darstellung der Schnittstellenklasse in der C-Sprache Zusammenfassung **

** überschreiben **

In der Sprache C wurden Funktionszeiger verwendet, um Schnittstellen darzustellen. Das heißt, es ist super einfach zu überschreiben. Überschreiben Sie einfach den Zeiger.

Wenn Sie also die "öffentliche Methode" unter Berücksichtigung von Überschreibungen definieren, ist es besser, einen Funktionszeiger zu verwenden. Das Beispiel wird weggelassen, da es nur überschrieben werden muss.

** Eindruck **

Es ist der Eindruck, dass ich lange im 0-2 geschrieben habe.

Ich bin nicht gut darin und es gibt einige Teile, die nicht in der objektorientierten Sprache selbst geschrieben sind. Objektorientiertes Design kann auch in C-Sprache korrekt ausgeführt werden, wenn Sie die alternative Ausdrucksmethode verwenden! Das ist mein Eindruck.

Es ist lange her, aber das war's.

Recommended Posts

Betrachten Sie eine einfach zu verwendende objektorientierte "Like" -Darstellung in C. ~ Teil 2 Interface Override
Überlegen Sie, ob das Programmieren in Python und C ein Anime war
Realisieren Sie die Schnittstellenklasse in der Sprache C.