gpt4 book ai didi

c++ - dlopen、工厂模式和虚方法表

转载 作者:行者123 更新时间:2023-11-27 23:57:06 27 4
gpt4 key购买 nike

在 C++ 中使用 dlopen 时,我正在努力思考工厂模式在内部是如何工作的。很抱歉发了很长的帖子。

tl;博士;问题在下面的粗体中。

来自 http://www.tldp.org/HOWTO/C++-dlopen/thesolution.html 的片段删除错误检查以节省空间:

主要.cpp

#include "polygon.hpp"
#include <iostream>
#include <dlfcn.h>

int main()
{
using std::cout;

// load the triangle library
void* triangle = dlopen("./triangle.so", RTLD_LAZY);

// load the symbols
// create function pointers
// (Exposed with extern "C")
polygon* create_triangle = (polygon*) dlsym(triangle, "create");
void* destroy_triangle = (void*) dlsym(triangle, "destroy");

// create an instance of the class
polygon* poly = create_triangle();

// use the class
poly->set_side_length(7);
cout << "The area is: " << poly->area() << '\n';

destroy_triangle(poly); // destroy the class

dlclose(triangle); // unload the triangle library

多边形.hpp

#ifndef POLYGON_HPP
#define POLYGON_HPP

class polygon
{
protected:
double side_length_;

public:
polygon()
: side_length_(0) {}

virtual ~polygon() {}

void set_side_length(double side_length)
{
side_length_ = side_length;
}

virtual double area() const = 0;
};

// the types of the class factories
typedef polygon* create_t();
typedef void destroy_t(polygon*);

#endif

三角形.hpp

#include "polygon.hpp"
#include <cmath>

class triangle : public polygon
{
public:
virtual double area() const
{
return side_length_ * side_length_ * sqrt(3) / 2;
}
};


// the class factories

extern "C" polygon* create()
{
return new triangle;
}

extern "C" void destroy(polygon* p)
{
delete p;
}

所以看看 main() 函数,我看到的是这个。

  1. dlopen 创建句柄。
  2. 创建函数指针以便三角形类可以创建新的三角形对象并销毁它。 (dlopen 为我们提供了一个可以分支到的内存位置。)
  3. create_triangle() 返回一个三角形转换成一个多边形(因为我们知道多边形的方法。
  4. 我们使用基类的 set_side_length 方法设置内部成员 side_length_。

这里是问题:

当调用 poly->area() 时,如何在三角形对象中找到它?

  • 我们知道基类在内存中的什么地方有它的“virtual area()”方法。
  • 由于“triangle.so”是动态加载的,编译器无法说我识别出三角形区域 () 正在覆盖程序中的多边形区域 ()。
  • 此时名称已完全损坏,.so 可以用 clang++ 编译,程序可以用 g++ 编译。因此,目前可能没有希望认出他们。

Virtual Member Table 是否根据虚拟方法出现的时间来保持它们的顺序?那么这段代码会破坏它吗?

多边形.hpp

...
virtual double area() const = 0;
virtual double parameter() const = 0;
...

三角形.hpp

...
double parameter() const { ... } // implementing and defining parameter first
area() const { ... } // implementing and defining second.
...

我知道你会想让它们保持有序......但是假设我们再进行几次子类化并且它们以不同的顺序定义......

在这方面的任何帮助都会很棒。我只是无法想象这里的内存中发生了什么才能让它真正起作用。

谢谢!很抱歉发了这么长的帖子。

最佳答案

When poly->area() is called how is this found in the triangle object?

poly 的所有初始化都发生在库中(包括设置 vptr)。调用者(即可执行文件)唯一要做的就是从特定索引处的 poly 虚表加载虚方法指针。 executable 和 shlib 都共享 poly 类的声明,因此它们都同意哪个 vtable 元素对应于 area

请注意,编译器不需要知道任何关于 poly 的实现如何重载基类。

the .so could have been compiled with clang++ and the program could have been compiled with g++

Clang 很难与 Linux 平台上的 GCC(Windows 平台上的 Visual Studio)兼容以实现这种互操作性。

I know you would want to keep them in order... but let's say we subclass a couple more times and they get defined in a different order...

子类化不会改变此时固定的基类 vtable 的结构(否则多态性也会破坏)。

关于c++ - dlopen、工厂模式和虚方法表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41832840/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com