由于C语言的特点,这里我们无需创建静态工厂类,直接调用make_product()
函数就行。
main.c:
#include "abs_product.h"
#include "con_productA.h"
#include "con_productB.h"
#include "con_factory.h"int
main (void)
{AbsProduct *pro;pro = make_product ("ConProductA");abs_product_print (pro);pro = make_product ("ConProductB");abs_product_print (pro);g_object_unref (pro);
}
输出结果为:
called print() from ConProductA
called print() from ConProductB
抽象产品类AbsProduct
:
abs_product.h:
#ifndef ABS_PRODUCT_H
#define ABS_PRODUCT_H#include <glib-object.h>#define ABS_TYPE_PRODUCT (abs_product_get_type())
G_DECLARE_DERIVABLE_TYPE (AbsProduct, abs_product, ABS, PRODUCT, GObject)struct _AbsProductClass {GObjectClass base_class;void (*print) (AbsProduct *self);
};void
abs_product_print (AbsProduct *self);#endif // ABS_PRODUCT_H
abs_product.c:
#include "abs_product.h"G_DEFINE_ABSTRACT_TYPE (AbsProduct, abs_product, G_TYPE_OBJECT)static void
abs_product_class_init (AbsProductClass *class_)
{class_->print = NULL;
}static void
abs_product_init (AbsProduct *instance)
{ }void
abs_product_print (AbsProduct *self)
{g_return_if_fail (ABS_IS_PRODUCT (self));AbsProductClass *class_ = ABS_PRODUCT_GET_CLASS (self);if (class_->print == NULL) {g_print ("纯虚函数print()未被覆盖\n");abort();}class_->print (self);
}
具体产品类ConProductA
:
con_productA.h:
#ifndef CON_PRODUCTA_H
#define CON_PRODUCTA_H#include "abs_product.h"#define CON_TYPE_PRODUCTA (con_productA_get_type())
G_DECLARE_FINAL_TYPE (ConProductA, con_productA, CON, PRODUCTA, AbsProduct)ConProductA *
con_productA_new();#endif // CON_PRODUCTA_H
con_productA.c:
#include "con_productA.h"struct _ConProductA {AbsProduct base_class;
};G_DEFINE_TYPE (ConProductA, con_productA, ABS_TYPE_PRODUCT)static void
override_print (AbsProduct *self)
{if (!CON_IS_PRODUCTA (self)) {g_print ("con_productA_print(): 不兼容的类型!");abort();}g_print ("called print() from ConProductA\n");
}static void
con_productA_class_init (ConProductAClass *class_)
{AbsProductClass *parent_class = ABS_PRODUCT_CLASS (class_);parent_class->print = override_print;
}static void
con_productA_init (ConProductA *instance)
{ }ConProductA *
con_productA_new()
{return g_object_new (CON_TYPE_PRODUCTA, NULL);
}
具体产品类ConProductB
:
con_productB.h:
#ifndef CON_PRODUCTB_H
#define CON_PRODUCTB_H#include "abs_product.h"#define CON_TYPE_PRODUCTB (con_productB_get_type())
G_DECLARE_FINAL_TYPE (ConProductB, con_productB, CON, PRODUCTB, AbsProduct)ConProductB *
con_productB_new();#endif // CON_PRODUCTB_H
con_product.c:
#include "con_productB.h"struct _ConProductB {AbsProduct base_class;
};G_DEFINE_TYPE (ConProductB, con_productB, ABS_TYPE_PRODUCT)static void
overide_print (AbsProduct *self)
{if (!CON_IS_PRODUCTB (self)) {g_print ("con_productB_print(): 不兼容的类型\n");abort();}g_print ("called print() from ConProductB\n");
}static void
con_productB_class_init (ConProductBClass *class_)
{AbsProductClass *parent_class = ABS_PRODUCT_CLASS (class_);parent_class->print = overide_print;
}static void
con_productB_init (ConProductB *instance)
{ }ConProductB *
con_productB_new()
{return g_object_new (CON_TYPE_PRODUCTB, NULL);
}
具体工厂类ConFactory
:
con_factory.h:
#ifndef CON_FACTORY_H
#define CON_FACTORY_H#include <glib-object.h>
#include "abs_product.h"#define CON_TYPE_FACTORY (con_factory_get_type())
G_DECLARE_FINAL_TYPE (ConFactory, con_factory, CON, FACTORY, GObject)AbsProduct *
make_product (const char *type);#endif // CON_FACTORY_H
con_factory.c:
#include "con_factory.h"
#include "con_productA.h"
#include "con_productB.h"#include <string.h>struct _ConFactory {GObject base_class;
};G_DEFINE_TYPE (ConFactory, con_factory, G_TYPE_OBJECT)static void
con_factory_class_init (ConFactoryClass *class_)
{ }static void
con_factory_init (ConFactory *instance)
{ }AbsProduct *
make_product (const char *type)
{AbsProduct *ret;if (strcmp (type, "ConProductA") == 0)ret = ABS_PRODUCT (con_productA_new());else if (strcmp (type, "ConProductB") == 0)ret = ABS_PRODUCT (con_productB_new());else {g_print ("没有该产品类型!\n");abort();}return ret;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.1)
project(demo)set(EXE main)aux_source_directory(. SRC)add_executable(${EXE} ${SRC})add_compile_options(${GLIB_CFLAGS_OTHER})find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB REQUIRED gobject-2.0)target_include_directories(${EXE} PUBLIC ${GLIB_INCLUDE_DIRS})
target_link_libraries(${EXE} PUBLIC ${GLIB_LIBRARIES})