对象创建和绑定的奇怪结果

Jat*_*tra 0 c++ dynamic-cast this

我错误地写了一些愚蠢的东西,令我惊讶的是.

class A
{    public:
        void print()
        {
            std::cout << "You can't/won't see me !!!" << std::endl;
        }  
        A* get_me_the_current_object()
        {
            return this;
        }
};  
int main()
{
    A* abc = dynamic_cast<A*>(abc);
    abc->print();
}
Run Code Online (Sandbox Code Playgroud)

在这里,A* abc = dynamic_cast<A*>(abc)我正在对一个未声明的指针进行dynamic_cast.但是,它有效,所以我认为上述陈述被打破为:

A* abc;
abc = dynamic_cast<A*>(abc);
Run Code Online (Sandbox Code Playgroud)

因此,它的工作原理.但是,在尝试一些更奇怪的场景时,例如:

A* abc;
abc->print();
Run Code Online (Sandbox Code Playgroud)

并进一步

A* abc = abc->get_me_the_current_object(); 
abc->print();
Run Code Online (Sandbox Code Playgroud)

我惊呆了,看着这些例子是如何运作的,并且映射已经完成.
有人可以详细说明这些是如何工作的吗?提前致谢.

Jon*_*ely 6

你犯了一个常见的错误,认为未定义的行为和C++错误意味着你应该期待看到一个戏剧性的崩溃或你的计算机着火.有时候没有任何事 这并不意味着代码"作品",因为它仍然有一个错误,它只是症状没有显示了... .

但是,它有效,所以我认为上述陈述被打破为:

是的,你所做的只是将未初始化的指针转换为相同的类型,即不需要转换,因此编译器什么都不做.您的指针仍然是相同的类型,仍然未初始化.

这类似于:

int i = i;
Run Code Online (Sandbox Code Playgroud)

根据C++的语法,这是有效的,因为i它在那个范围内,但是未定义,因为它复制了一个未初始化的对象.虽然它实际上不太可能让你的计算机着火,它似乎"工作".

有人可以详细说明这些是如何工作的吗?

从技术上讲,你是取消引用一个无效的指针,这是一个未定义的行为,但由于你的成员函数实际上并没有使用该对象的任何成员,因此无效的this指针不会被解引用,因此代码"有效"(或至少看起来像. )

这类似于:

void function(A* that)
{
    std::cout << "Hello, world!\n";
}
A* p;
function(p);
Run Code Online (Sandbox Code Playgroud)

因为that没有使用指针(就像this你的成员函数中没有使用指针一样),这不一定会崩溃,尽管它可能会在甚至复制未初始化的指针可能导致硬件故障的实现上发生.在您的示例中,您的编译器似乎不需要取消引用abc来调用非静态成员函数,并将其作为隐藏this参数传递不会导致硬件错误,但即使它没有失败,行为仍未定义以一种明显的方式,如段错误..