hacqing

春风扫落叶...

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

我理解的多态.

今天睡到4:30就醒了, 没有睡意了, 打开了电脑. 闲逛了下. 突然想起以前面试的时候被问到的一个问题: c如何实现多态?

自己也就想了想, 搜索了下, 确实有这方面的文章, 这段时间基本上没心思去阅读那些文字多多的文章, 该怎么办呢? 只能自己想呀...

1. 多态的前提是: 继承.

//c++ code:
//---------------------------begin------------------------------//
class BaseClass1
{
  int member;
};

class BaseClass2
{
  int member;
};

//单继承
class SubClass: public BaseClass1
{
  int member;
}
//多继承
class SubClass: public BaseClass1, BaseClass2
{
  int member;
}
//----------------------------end-------------------------------//

//c code:
//---------------------------begin------------------------------//
typedef struct BaseClass1
{
    int member;
} BaseClass1;

typedef struct BaseClass2
{
  int member;
} BaseClass2;

//单继承
typedef struct SubClass
{
    BaseClass1 super;
  int member;
} SubClass;

//多继承
typedef struct SubClass
{
  BaseClass1 super1;
  BaseClass2 super2;
  int member;
} SubClass;
  //----------------------------end-------------------------------//

 

2. c/c++对比实现多态

//c++ 多态
#include <iostream> class Person { public: virtual void echo_work_type(void) = 0; }; class Student: public Person { public: void echo_work_type(); }; void Student::echo_work_type(void) { std::cout<< "learn." << std::endl; } class Teacher: public Person { public: void echo_work_type(); }; void Teacher::echo_work_type(void) { std::cout<< "learn and teach." << std::endl; } int main(int argc, char* argv[]) { Student s; Teacher t; Person * pp; pp = (Person *)&s; pp->echo_work_type(); pp = (Person *)&t; pp->echo_work_type(); return 0; }

 

// c 实现多态, 没有使用vir_ptr and vir_table
#include <stdio.h>

typedef struct Person
{
//  void * vir_ptr;
    void (*virtual_echo_work_type)(void);
} Person;

typedef struct Student
{
    Person super;
    void (*learning)(int times);

    void (*construct)(struct Student * s);
    void (*desconstruct)(void);
} Student;

void student_echo_work_type(void)
{
    printf("learn.\n");
    return ;
}

void student_learning(int times)
{
    printf("play game anytime if not rest time.\n");
}

void student_construct(Student * s)
{
    s->super.virtual_echo_work_type = student_echo_work_type;
    s->learning = student_learning;
}

typedef struct Teacher
{
    Person super;
    void (*teaching)(int times);

    void (*construct)(struct Teacher *t);
    void (*desconstruct)(void);
} Teacher;

void teacher_echo_work_type(void)
{
    printf("learn and teach.\n");
    return ;
}

void teacher_teaching(int times)
{
    printf("$$$$$$$$$$$\n");
}

void teacher_construct(Teacher *t)
{
    t->super.virtual_echo_work_type = teacher_echo_work_type;
    t->teaching = teacher_teaching;
}


int main(void)
{
    Student s = { 0 };
    Teacher t = { 0 };
    Person * pp = 0;

    s.construct = student_construct;
    s.construct(&s);
    
    t.construct = teacher_construct;
    t.construct(&t);
    
    pp = (Person *)&s;
    pp->virtual_echo_work_type();
    pp = (Person *)&t;
    pp->virtual_echo_work_type();
    return 0;
}

 

// c实现多态, 使用vir_ptr and vir_table
#include <stdio.h>
#include <string.h>

typedef struct Note
{
    char * fun_name;
    void * fun_address;
} Note;

typedef struct Person
{
    void * vir_ptr;
    void (*virtual_echo_work_type)(struct Person *p);
} Person;

void echo_work_type(Person * p)
{
    Note * vir_ptr = (Note *)(p->vir_ptr);
    char * fun_name = __FUNCTION__;
    while (vir_ptr->fun_name != 0)
    {
        if (strstr(vir_ptr->fun_name, fun_name) != 0)
        {
            break;
        }
        ++ vir_ptr;
    }
    if (vir_ptr != 0)
    {
        ((void (*)(Person *))vir_ptr->fun_address)(p);
    }
    return ;
}

typedef struct Student
{
    Person super;
    void (*learning)(int times);

    void (*construct)(struct Student * s);
    void (*desconstruct)(void);
} Student;

void student_echo_work_type(Student *s)
{
    printf("learn.\n");
    return ;
}

void student_learning(int times)
{
    printf("play game anytime if not rest time.\n");
}

void student_construct(Student * s)
{
    Note * vir_table = (Note *)malloc(sizeof(Note) * 2);    //2 这个数字可以根据有多少个虚函数来确定
    if (vir_table == 0)
    {
        //throw exception.
        return ;
    }
    s->super.vir_ptr = (void *)vir_table;
    vir_table[0].fun_address = (void *)student_echo_work_type;
    vir_table[0].fun_name = (char *)malloc((strlen("student_echo_work_type") + 1) * sizeof(char));
    strcpy(vir_table[0].fun_name, "student_echo_work_type");

    s->super.virtual_echo_work_type = echo_work_type;

    vir_table[1].fun_address = 0;
    vir_table[1].fun_name = 0;
    s->learning = student_learning;
}

typedef struct Teacher
{
    Person super;
    void (*teaching)(int times);

    void (*construct)(struct Teacher *t);
    void (*desconstruct)(void);
} Teacher;

void teacher_echo_work_type(Teacher * t)
{
    printf("learn and teach.\n");
    return ;
}

void teacher_teaching(int times)
{
    printf("$$$$$$$$$$$\n");
}

void teacher_construct(Teacher *t)
{
    Note * vir_table = (Note *)malloc(sizeof(Note) * 2);    //2 这个数字可以根据有多少个虚函数来确定
    if (vir_table == 0)
    {
        //throw exception.
        return ;
    }
    t->super.vir_ptr = (void *)vir_table;
    vir_table[0].fun_address = (void *)teacher_echo_work_type;
    vir_table[0].fun_name = (char *)malloc((strlen("teacher_echo_work_type") + 1) * sizeof(char));
    strcpy(vir_table[0].fun_name, "teacher_echo_work_type");

    t->super.virtual_echo_work_type = echo_work_type;

    t->teaching = teacher_teaching;
}


int main(void)
{
    Student s = { 0 };
    Teacher t = { 0 };
    Person * pp = 0;

    s.construct = student_construct;
    s.construct(&s);
    
    t.construct = teacher_construct;
    t.construct(&t);
    
    pp = (Person *)&s;
    pp->virtual_echo_work_type(pp);
    pp = (Person *)&t;
    pp->virtual_echo_work_type(pp);
    return 0;
}

 

 

 

 

posted on 2012-05-06 10:13  hacqing  阅读(139)  评论(0)    收藏  举报