gpt4 book ai didi

c++ - 如何检查两个指针​​是否指向同一个对象?

转载 作者:IT老高 更新时间:2023-10-28 22:41:50 28 4
gpt4 key购买 nike

考虑两个指针

A* a; 
B* b;

A 和 B 都是多态类。如何判断a和b是否指向同一个对象?

更准确地说,如果存在某个类型为 D 的对象 d 使得 *a 和 *b 都在 d 的类层次结构中的某个位置,则让我们指定 a 和 b 指向同一个对象。

我会提出以下解决方案:

dynamic_cast<void*>(a) == dynamic_cast<void*>(b)

确实,按照标准,

dynamic_cast<void*>(v) 

yields “指向 v 指向的最衍生对象的指针。(n3242.pdf:§ 5.2.7 - 7)。如果两者的派生最多的是同一个对象,则指针指向同一个对象。

我很确定从实用的角度来看它应该始终正常工作。但理论上,乍一看,提议的相等性似乎会产生误报,例如,如果 b 指向 A 的第一个成员(而不是 A 的祖先)。尽管实际上不可能为 A 及其成员获得相等的地址,因为 A 的虚拟表指针应该位于该成员之前,但该标准并未强制要求虚拟表,也没有说明类布局。

所以,我的问题是:

  1. 从标准的角度来看,建议的解决方案是否正确?

  2. 对于私有(private)( protected )继承或 cv 限定是否有任何警告?

  3. 有更好的解决方案吗?

[编辑]

我试图举一些例子来说明一个相对复杂的场景。在这种情况下,动态交叉转换和静态转换是不明确的。

 // proposed impplementation:
template<typename P, typename Q>
bool test_ptrs(const P* p, const Q* q)
{
return (dynamic_cast<const void*>(p) == dynamic_cast<const void*>(q));
}


struct Root
{
virtual ~Root(){};
};

struct A: public Root // nonvirtually
{
};

struct B: public Root // nonvirtually
{
};

struct C: public A, B // nonvirtual diamond started with Root
{
Root another_root_instance;
};

int main()
{
C c;

A* pa= &c;
B* pb= &c;

bool b = (dynamic_cast<void*>(pa) == dynamic_cast<void*>(pb));

Root* pra= dynamic_cast<Root*> (pa);
Root* prb= dynamic_cast<Root*> (pb);

//Root* prc= dynamic_cast<Root*> (&c); // runtime error, ambiguous cast
Root* prr= dynamic_cast<Root*>(pra);

Root* pcar= dynamic_cast<Root*>(pra);
Root* pcbr= dynamic_cast<Root*>(prb);

if(
test_ptrs(pa, pb)
&& test_ptrs(pra, prb)
&& !test_ptrs(pa,&c.another_root_instance)
)
{
printf("\n test passed \n");
}
}

最佳答案

在我看来,解决这个问题的最不臭的方法是为 A & B 引入一个基类:

#include <iostream>

struct Base
{
virtual ~Base() {};
};

struct A : public virtual Base
{
int a;
virtual ~A() {};
virtual void afunc() {};
};



struct B : public virtual Base
{
int b;
virtual ~B() {};
virtual void bfunc() {};
};

struct C: A, B
{};

int main()
{
C c;
A *a = &c;
B *b = &c;

std::cout << "a* == " << &(*a) << std::endl;
std::cout << "b* == " << &(*b) << std::endl;
std::cout << "a == b == " << ((void*)a == (void*)b) << std::endl;

Base* ba = a;
Base* bb = b;

std::cout << "ba* == " << &(*ba) << std::endl;
std::cout << "bb* == " << &(*bb) << std::endl;
std::cout << "ba == bb == " << (ba == bb) << std::endl;

return 0;
}

关于c++ - 如何检查两个指针​​是否指向同一个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9974596/

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