首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果涉及抽象类,为什么一个指向派生的指针和一个指向同一个地址的指针不指向?

如果涉及抽象类,为什么一个指向派生的指针和一个指向同一个地址的指针不指向?
EN

Stack Overflow用户
提问于 2020-04-24 10:41:17
回答 1查看 49关注 0票数 0

我遇到了一个可以简化为以下示例的问题:

代码语言:javascript
复制
#include "iostream"

struct A {
    char a;
};
struct B : A {
    virtual void f() = 0;
};
struct C : B {
    void f() override {}
};

void f(A* fpa) {
    std::cout << fpa << '\n' << reinterpret_cast<C*>(fpa) << std::endl;
}

int main() {
    C c {};
    A* pa {&c};
    std::cout << &c << '\n' << pa << '\n' << reinterpret_cast<C*>(pa) << std::endl;
    f(&c);
}

pafpa都不会一直指向c的地址,尽管两者都是用&c初始化的。所有打印在&c之后的地址都被+8所抵消(用g++和clang++测试)。删除A::a或B::f()和C::f()或用pafpa初始化reinterpret_cast<A*>(&c),而不仅仅是&c修复地址。

但我为什么要这么做?既然所有的继承都是公共的,那么在这种情况下,难道任何A*都不能将地址保存到任何ABC吗?为什么价值会隐式变化?我是否可以将警告标志传递给g++或clang++来警告这种行为?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-24 10:47:38

或用reinterpret_cast<A*>(&c)初始化pa和fpa,而不仅仅是&c修复地址。

这并不能“修正”地址。那会破坏地址。它产生一个无效的指针。

,但我为什么要这么做呢?

你没必要那么做。偏移地址是基子对象的正确地址。

--如果涉及抽象类,为什么没有指向派生的指针和指向相同地址的指针?

因为在基本子对象之前有一些东西存储在对象中。

不应该有任何A*能够将地址保存到任何A、B或C

不是的。指向A的有效指针的地址总是A对象的地址。如果导出了动态类型,那么该对象就是基子对象。基可以存储在派生类开始时的偏移量处。

,因为所有继承都是公共的

在这方面,继承的可获得性与此无关。

以及是否有警告标志可以传递给g++或clang++来警告这种行为?

我非常怀疑是否会有。我也不明白为什么在这种情况下你会想要一个警告。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61406488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档