从构造函数调用全局函数

10

我有这段代码:

#include <iostream>
using namespace std;

struct A;
struct B;

void g(A* a){ cout << "A";}
void g(B* b){ cout << "B";}

struct A{
    A(){ g(this); }
};

struct B : A{
    B(){}
};


int main() {
    B* b=new B();
    return 0;
}

输出结果为:

A

这是否意味着传递给构造函数 A()this 指针的类型是 A*


您的代码中没有虚拟函数,因此所有的类型检查都是纯静态的。 - Angew is no longer proud of SO
2
@Angew:虽然这与问题关系不大。 - Kerrek SB
@Angew如果我在A中添加一个虚方法,输出仍然是一样的。 - Loay
@KerrekSB 我会说它确实有。在 A 的成员函数内部,this 的静态类型实际上除了 A* 之外别无选择。 - Angew is no longer proud of SO
1
关于虚拟函数的评论是针对问题中的“绑定步骤”部分的:只涉及静态绑定。 - Angew is no longer proud of SO
在A的构造函数中,this的动态类型也是A。即使对象最终将成为B对象。 - Martin Bonner supports Monica
3个回答

12

是的。

问题在于,一个B对象也是一个A对象。当您在A的函数内部时,类不知道它是否为B。因此this-ptr将是类型为A*的指针。

当您在B内调用函数时,它则为B*


绑定是静态完成的。如果我在A中添加一个虚方法,绑定仍然是静态的吗? - Loay
我的回答与静态绑定没有真正的关系,但那时仍然是正确的。另外对于虚方法问题:当您使用继承时,应始终声明基类的析构函数为虚拟的。 - Hayt
3
如果你对构造函数中的动态多态有兴趣,可以在该网站上搜索“virtual functions”。指针使用时,无论用于何种目的,this 的类型始终为A*。但如果你使用它来调用虚函数,则最派生对象在其自己的构造函数中也是 A-子对象,这一点很重要。只有当该对象的生命开始后,即在其中一个构造函数返回之后,它才成为完整对象。 - Kerrek SB
不,它不是。从技术上讲,它是类型为 A* 的。这个答案是错误的。 - skypjack
@skypjack 是的,你说得对。我假设大家明白我指的是this-ptr的类型而不是this的类型。现在已经修复了这个问题。 - Hayt
当您在 A 函数内部时,类不知道它是否为 B。更准确地说,在 A 的构造函数期间,它还不是 B。 - Lightness Races in Orbit

8

[9.2.2.1/1]中提到的,类X的成员函数中this的类型为X*。

注意构造函数是特殊成员函数,A是B的子对象,因此在A的成员函数体内,this指针的类型为A*,而在B的成员函数中则为B*。

还要注意的是,来自A和B的this指针也可以有不同的值,即它们可以指向不同的子对象。
例如:

#include<iostream>

struct A {
    A() { std::cout << this << std::endl; }
    int i{0};
};

struct B: A {
    B() { std::cout << this << std::endl; }
    virtual void f() {}
};

int main() {
    B b;
}

话虽如此:

这是否意味着传递给构造函数 A()this指针的类型是A类型?

不,它的类型是A*


编辑

尽管 OP 编辑了问题并更改了其含义,但我更愿意在这个答案中保留原始问题的引用。
回滚可能是该编辑的适当操作。
无论如何,答案仍然适用。


4
是的,这正是它的意思。

@skypjack 是的,那就是 OP 说的。 - Hatted Rooster
@GillBates 这是 OP 修改他的问题的方式,而不是他所说的内容。请查看我的答案或问题历史记录以了解他所说的内容。 - skypjack
1
@GillBates 实际上他修改了问题,现在它是一个完全不同的问题,所以原帖作者应该回滚编辑。 - skypjack
@BWA:这真的就是问题的答案。请在审查时多加注意。 - Lightness Races in Orbit
1
@skypjack,我编辑了问题以供日后参考。问题的意图不在于类型是指针还是非指针,而在于类的类型。 - Loay
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接