代码片段的输出结果不是我预期的。

huangapple go评论62阅读模式
英文:

The output of the code snippet is not what i expected

问题

我不明白为什么这段使用修改版本的访问者模式的代码片段总是打印出日志 "V" 而不是 "A"。使用 C++11 版本编译。

我执行了这段代码片段,我期望在输出控制台中看到日志 "A"。
英文:

I don't understand why this code snippet using an altered version of the visitor patters is always printing the log V instead of A. Compiled using c++11 version.

#include <iostream>

using namespace std;

class A;
class B;
class Visitable;

class Visitor
{
    public:
    void visit(const A& a)
    {
        std::cout << "A" << std::endl;
    }
    
    void visit(const Visitable& v)
    {
        std::cout << "V" << std::endl;
    }
    
    void visit(const B& b)
    {
        std::cout << "B" << std::endl;
    }
};

class Visitable
{
    public:
        virtual void Accept(Visitor* visitor)
        {
            visitor->visit(*this);
        }
};

class A : public Visitable
{
};

class B : public Visitable
{
};

int main()
{
    Visitor* v = new Visitor();
    A* a = new A();
    
    a->Accept(v); // IT PRINTS V INSTEAD OF A.

    return 0;
}

I executed the code snipped, i was expecting to see the log A in the output console.

答案1

得分: 0

 visitor->visit(*this);

这是Visitable类的一个方法。因此,this是指向Visitable的指针。结束。

即使这个类的实例是一个子类,这仍然是正确的。this仍然是指向Visitable的指针,这就是C++的工作方式。这是重载解析结果的原因。


<details>
<summary>英文:</summary>

visitor->visit(*this);

This is a method of the `Visitable` class. Because of that, `this` is a pointer to a `Visitable`. The End.

This is true even if this instance of a class is a subclass. `this` is still a pointer to a `Visitable`, that&#39;s just how C++ works. That&#39;s the reason for the result of the overload resolution.



</details>



# 答案2
**得分**: 0

`*this` 的类型是 `Visitable`,与成员函数 `void Visitor::visit(const Visitable&)` 中参数的类型匹配,因此它是唯一可行的选择,因此被选中。

也就是说,另外两个成员函数 `void Visitor::visit(const A&)` 和 `void Visitor::visit(const B&)` 不可行,因为在调用 `visitor->visit(*this);` 中传递的参数类型是 `Visitable`,而这些成员函数的参数类型分别是 `const A&` 和 `const B&`。

> 为什么 `this` 是指向 `Visitable` 而不是 `A`

因为根据标准,在类 `X` 的非常量非静态成员函数 `func` 的函数体内,指针 `this` 的类型是 `X*`。这意味着 `*this` 是 `X`。这可以从[这里](https://en.cppreference.com/w/cpp/language/this)看到:

> 表达式 `this` 是一个 prvalue 表达式,其值是**隐式对象参数的地址**(非静态成员函数被调用的对象)。

<details>
<summary>英文:</summary>

The type of `*this` is `Visitable` which matches the type of the parameter in the member function `void Visitor::visit(const Visitable&amp;)` so that it is the only **viable** option and hence selected.

That is, the other two member function `void Visitor::visit(const A&amp;)` and `void Visitor::visit(const B&amp;)` are not viable since the passed argument in the call `visitor-&gt;visit(*this);` is of type `Visitable` while the parameter type in these member functions is `const A&amp;` and `const B&amp;` respectively.

---

&gt; why is `this` a pointer to Visitable instead of `A`

Because as per the standard, inside the body of a non-const non-static member function `func` of a class `X`, the type of pointer `this` is `X*`. This means that `*this` is `X`. This can be seen(pun intended) from [this](https://en.cppreference.com/w/cpp/language/this):

&gt; The expression this is a prvalue expression whose value is the **address of the implicit object parameter** (object on which the non-static member function is being called).


</details>



huangapple
  • 本文由 发表于 2023年2月23日 21:24:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75545458.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定