确定 C++ 中成员的类实例
Determine class instance of a member in C++
我从未在任何语言中看到过这个,但我想知道这是否可以使用一些我不知道的技巧。
假设我有一个类似
struct A {
// some members and methods ...
some_t t;
// more members ...
};
void test(some_t& x) { // a reference to avoid copying a new some_t
// obtain the A instance if x is the t member of an A
// or throw an error if x is not the t member of an A
...
// do something
}
是否有可能获得其成员t
x
的A
实例?
不,不幸的是,这是不可能的。
如果你知道你对某个A
实例的t
成员有引用,你可以使用 container_of
来获取实例,例如 A* pa = container_of(&x, A, t);
.
验证生成的指针是否确实是A
在技术上是可能的,当且仅当A
具有虚拟成员时,不幸的是,没有可移植的方法可以检查。
但是,您可以使用多重继承和dynamic_cast
来实现类似的东西,这允许子对象之间的交叉转换。
您可以在some_t
内部添加指向A
的指针(当然,如果some_t
是struct
或class
)
喜欢这个:
struct some_t
{
A *a;
...
};
void test(some_t& x)
{
if( x.a )
{
// do some
}
else
throw ...
}
如果你可以修改结构 A 及其构造函数,并且如果你能确保结构打包,你可以直接在 t 后面添加一个值,它包含一些魔术键。
struct A {
...
some_t t
struct magic_t
{
uint32 code
some_t* pt;
} magic;
}
#define MAGICCODE 0xC0DEC0DE //or something else unique
在 A 的构造函数中,执行以下操作: this->magic.code = MAGICCODE; this->magic.pt = &(this->t);
然后你可以写
bool test(some_t *t) //note `*` not `&`
{
struct magic_t* pm = (struct magic_t*)(t+1);
return (pm->pt == t && pm->code == MAGICCODE);
}
这个答案不符合原始问题的所有要求,我已经删除了它,但 OP 要求我发布它。它显示了如何在非常特定的条件下计算从指向成员变量的指针的实例指针。
您不应该这样做,但您可以:
#include <iostream>
#include <cstddef>
using namespace std;
struct A
{
int x;
int y;
};
struct A* find_A_ptr_from_y(int* y)
{
int o = offsetof(struct A, y);
return (struct A*)((char *)y - o);
}
int main(int argc, const char* argv[])
{
struct A a1;
struct A* a2 = new struct A;
cout << "Address of a1 is " << &a1 << endl;
cout << "Address of a2 is " << a2 << endl;
struct A *pa1 = find_A_ptr_from_y(&a1.y);
struct A *pa2 = find_A_ptr_from_y(&(a2->y));
cout << "Address of a1 (recovered) is " << pa1 << endl;
cout << "Address of a2 (recovered) is " << pa2 << endl;
}
输出
Address of a1 is 0x7fff5fbff9d0
Address of a2 is 0x100100080
Address of a1 (recovered) is 0x7fff5fbff9d0
Address of a2 (recovered) is 0x100100080
警告:如果你传递给find_A_ptr_from_y
的不是指向(结构A).y的指针,那么你很可能会得到垃圾。
你不应该(几乎)永远不要这样做。请参阅下面的DasBoot评论。
我不太清楚你想做什么,但是如果你想在知道指向 A 成员的指针时找到指向结构 A 实例的指针,你可以这样做。
例如,请参阅 linux 内核中的container_of宏。
test()
的参数x
不必是任何类的成员,只要test()
是融合的。
如果在语义上在特定应用程序中x
必须始终是类的成员,那么可以通过传递额外的参数或让some_t
本身包含此类信息来提供该信息。 然而,这样做是非常不必要的,因为如果test()
真的需要访问包含x
的对象,那么为什么不简单地传递父对象本身呢? 或者只是test()
成为同一类的成员函数,不传递任何参数? 如果原因是x
可能属于不同的类,则可以采用多态性来解决此问题。
基本上,我建议在任何情况下,您都不需要以更简单,更安全和更面向对象的方式解决这种功能。
- 依赖于类成员属性的类实例成员
- 实例成员与静态成员与非类方法的开销
- 将成员函数分配给实例成员的属性
- 向量映射作为实例成员的C 地图
- 如何转发声明模板实例成员函数
- 如何确保父实例成员的销毁
- 访问模板类型实例成员
- boost :: Spirit :: Qi-与语法结构中的实例成员一起工作
- 如何使用类实例成员函数指针填充函数指针成员
- C func 到C++具有非双射参数类型映射的实例成员蹦床
- 当拥有的对象退出范围时,在类实例成员上使用shared_ptr是否会正确清理
- 类实例成员初始化
- 无效SetSomeValue(int i);实例成员函数跟踪谁使用SetSomeValue()设置了SomeValue成
- 重新分配作为实例成员的数组
- 回调需要const函数,如何传递对象的实例成员
- 如何通过std::shared_ptr访问实例成员变量
- c++类实例成员是如何在机器级别传递的
- 指向实例成员的函数指针
- 如何使用 Python C/C++ 接口将实例成员函数作为 PyCFunction 类型传递
- 如何将实例成员函数作为回调传递给 std::thread