Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何实现C++;C语言中的虚函数 C++语言提供了虚拟函数。在纯C语言实现的约束下,如何实现类似的效果_C++_C_Language Implementation - Fatal编程技术网

如何实现C++;C语言中的虚函数 C++语言提供了虚拟函数。在纯C语言实现的约束下,如何实现类似的效果

如何实现C++;C语言中的虚函数 C++语言提供了虚拟函数。在纯C语言实现的约束下,如何实现类似的效果,c++,c,language-implementation,C++,C,Language Implementation,是对虚拟函数的描述 在普通C中无法实现虚拟函数,因为C没有继承的概念 更新: 正如在下面的注释中所讨论的,可以使用结构和函数指针在直C中执行类似于虚函数的操作。但是,如果你习惯了一种C++语言,它具有“真”虚函数,你可能会发现C++近似远不如它的优雅和使用。它们指的是依赖于特定对象实例的方法,而不是您当前携带它们的类型 换句话说:如果您将一个对象实例化为Bar,然后将其强制转换为Foo,则虚拟方法仍将是实例化时的方法(在Bar中定义),而其他方法将是来自Foo的方法 虚拟函数通常是通过vtabl

是对虚拟函数的描述

在普通C中无法实现虚拟函数,因为C没有继承的概念

更新:
正如在下面的注释中所讨论的,可以使用结构和函数指针在直C中执行类似于虚函数的操作。但是,如果你习惯了一种C++语言,它具有“真”虚函数,你可能会发现C++近似远不如它的优雅和使用。它们指的是依赖于特定对象实例的方法,而不是您当前携带它们的类型

换句话说:如果您将一个对象实例化为Bar,然后将其强制转换为Foo,则虚拟方法仍将是实例化时的方法(在Bar中定义),而其他方法将是来自Foo的方法

虚拟函数通常是通过vtables实现的(您可以对vtables做更多的研究;)

通过使用结构作为穷人的对象并在其中保存函数指针,可以在C中模拟类似的东西

(更准确地说,非虚函数使该类的模糊性从方法中被提取,但实际上我相信C++使用当前类型)

从.< /p>中盗取。 <>从C++类

class A {
protected:
    int a;
public:
    A() {a = 10;}
    virtual void update() {a++;}
    int access() {update(); return a;}
};
可以派生C代码片段。使用C++(AutoScript)的三个C++成员函数使用离线(独立)代码重写,并由地址收集到一个名为<> AyHuffiTe> <代码>的结构中。
A
的数据成员,并与函数表组合成名为
A
的C结构

struct A;

typedef struct {
    void (*A)(struct A*);
    void (*update)(struct A*);
    int (*access)(struct A*);
} A_functable;

typedef struct A{
    int a;
    A_functable *vmt;
} A;

void A_A(A *this);
void A_update(A* this);
int A_access(A* this);

A_functable A_vmt = {A_A, A_update, A_access};

void A_A(A *this) {this->vmt = &A_vmt; this->a = 10;}
void A_update(A* this) {this->a++;}
int A_access(A* this) {this->vmt->update(this); return this->a;}

/*
class B: public A {
public:
    void update() {a--;}
};
*/

struct B;

typedef struct {
    void (*B)(struct B*);
    void (*update)(struct B*);
    int (*access)(struct A*);
} B_functable;

typedef struct B {
    A inherited;
} B;

void B_B(B *this);
void B_update(B* this);

B_functable B_vmt = {B_B, B_update, A_access};

void B_B(B *this) {A_A(this); this->inherited.vmt = &B_vmt; }
void B_update(B* this) {this->inherited.a--;}
int B_access(B* this) {this->inherited.vmt->update(this); return this->inherited.a;}

int main() {
    A x;
    B y;
    A_A(&x);
    B_B(&y);
    printf("%d\n", x.vmt->access(&x));
    printf("%d\n", y.inherited.vmt->access(&y));
}

比必要的更详细,但它能说明问题。

@GCC…虚拟函数在对象的基类中声明,然后在子类中“重写”或实现。i、 例如,假设您有Vehicle基类,您创建了两个子类,Motorcycle和Automobile。基类将声明AddTyres()的虚拟函数,然后子类将实现此函数,每个子类将以不同的方式实现它。汽车有四个轮子,而摩托车有两个。不过,我不能给你C或C++的语法。希望这有助于

为什么你要再次实现C++?像这样的话题很容易在书中找到,网上也有很多文章。通过问这些问题,你的声誉会受到影响,人们会开始认为你是理所当然的。所以尽你所能找到答案,但仍然不能问:)。听起来你的老师需要从学术界休息一下,找一份真正的编程工作。如果这不是一个真正的问题,为什么会有很多答案,为什么???我试图改进这个问题的措辞,让它更清楚,可以重新打开,得到有启发性和有用的答案。搜索[[c]面向对象的](://stackoverflow.com/search?q=[c]+面向对象的)产生:其中罗杰发布的一个问题对这个版本的问题有最好的答案。实际上,C中有继承的概念,但它不尊重这里的访问控制:GullU:C++结构是不象C结构的。不能直接做(类缺少:))但是使用结构和函数指针实现这样的系统是没有问题的。注意到(通常)可以与C++的虚函数互操作,如果足够的C++已知的ABI。例如,Windows COM使用虚拟函数来声明接口,并且有一种技术(仅由大量宏使用)用于声明COM接口并从C调用它们。C++还启动了生命(包括许多当前的特性,包括虚拟函数)。作为一个预处理器,它读取C++文本并编写C。因此,在C++中实现它们是可能的,只是不愉快。在C语言中,你所能做的就是通过在你传递的结构上存储指向你的函数的指针来模拟它。当然,我的答案是基于C#和对象模型+1的一个很好的例子:这几乎可以将vtables转换为C,并且比C程序员做函数指针转换或函数指针的转换结构等事情要优雅得多。它仍然笨重和笨拙,但是嘿,C不是为这个而设计的。@Study472:我同意你的观点,但是当有人需要这样的代码时,它就毫无意义了。某些语言更适合某些问题。这是事实,但我不得不在C系统中工作,试图实现OOP。他们通过使用函数指针强制转换结构(比如强制转换结构A),而不仅仅是为多态性传递A,并允许每个子类(比如结构)简单地存储A并为其分配适当的函数地址和数据。这至少比结构转换或转换函数指针要优雅得多。我认为虚拟表中不存在A::access(),因为这是一个非virt函数。请注意:开头的链接已断开。