[英]What is the best way to determine object pointer by pointer to one of it's members?
[英]How to copy object which contains a pointer to one of several other members?
考虑一下:
class Base {};
class A : public Base {};
class B : public Base {};
class C : public Base {};
class D : public Base {};
class Obj
{
public:
Obj(const Obj&);
private:
A _a;
B _b;
C _c;
D _d;
Base *_current;
};
_current
始终指向_a
, _b
, _c
或_d
。 A
, B
, C
和D
可以具有不同的大小。 我想实现Obj(const Obj&)
以便副本的_current
指向自身本身的适当成员。
这种方法安全吗?
Obj::Obj(const Obj& obj) :
_a {obj._a},
_b {obj._b},
_c {obj._c},
_d {obj._d}
{
auto objAAddr = reinterpret_cast<const char *>(&obj._a);
auto objCurAddr = reinterpret_cast<const char *>(obj._current);
auto diff = objCurAddr - objAAddr;
auto myAAddr = reinterpret_cast<char *>(&_a);
_current = reinterpret_cast<Base *>(myAAddr + diff);
}
“基地”地址可能是一些比其他_a
“在这儿,就像&_obj
(然后应用差异this
)。
有更好/更清洁的选择吗?
要计算_current
您应该添加到this
之间的区别obj._current
和&obj
。 为了正确计算偏移量,您应该使用特殊类型uintptr_t
。 char *
不适合,因为在某些特定平台上char
超过一个字节。
#include <cstdint>
Obj::Obj(const Obj& obj) :
_a {obj._a},
_b {obj._b},
_c {obj._c},
_d {obj._d}
{
_current = reinterpret_cast<Base *>(reinterpret_cast<uintptr_t>(this) +
(reinterpret_cast<const uintptr_t>(obj._current) -
reinterpret_cast<const uintptr_t>(&obj)));
}
我将在此处使用C样式转换:
Obj::Obj(const Obj& obj) :
_a {obj._a},
_b {obj._b},
_c {obj._c},
_d {obj._d}
{
_current = (Base *)((uintptr_t)this +
((const uintptr_t)obj._current - (const uintptr_t)&obj));
}
临时多态性无需使用脆弱的指针算法即可实现。
class Base {};
class A : public Base {};
class B : public Base {};
class C : public Base {};
class D : public Base {};
class Obj
{
public:
Obj(const Obj&);
Obj() { set_current(aa); }
private:
A _a;
B _b;
C _c;
D _d;
Base *_current;
enum base_tag {
aa, bb, cc, dd
} tag;
void set_current(base_tag t) {
tag = t;
switch (tag) {
case aa: _current = &_a; break;
case bb: _current = &_b; break;
case cc: _current = &_c; break;
case dd: _current = &_d; break;
default: throw("gulp");
}
}
};
Obj::Obj(const Obj& obj) :
_a {obj._a},
_b {obj._b},
_c {obj._c},
_d {obj._d}
{
set_current(obj.tag);
}
int main() {
Obj o1;
Obj o2{ o1 };
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.