this->field 与 C++ 中的 this.field
this->field vs. this.field in C++
行 (2)
和 (3)
如何在以下 C++ class 中编译,鉴于 this
是一个指针,所以应该需要 ->
访问字段的符号(如 (1)
行所示)? (Source)
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
template <typename T>
class sptr_wrapper
{
private:
boost::shared_ptr<T> sptr;
public:
template <typename ...ARGS>
explicit sptr_wrapper(ARGS... a)
{
this->sptr = boost::make_shared<T>(a...);
}
explicit sptr_wrapper(boost::shared_ptr<T> sptr)
{
this->sptr = sptr; // (1)
}
virtual ~sptr_wrapper() noexcept = default;
void set_from_sptr(boost::shared_ptr<T> sptr)
{
this.sptr = sptr; // (2)
}
boost::shared_ptr<T> get_sptr() const
{
return sptr; // (3)
}
};
行(2)
无效。正如你所说,this
是一个指针,我们需要使用->
而不是.
作为class template的成员,sptr_wrapper::set_from_sptr
在使用之前不需要实例化。所以你可以添加一些代码来尝试调用它,然后你可能会如你所料得到编译错误。
This applies to the members of the class template: unless the member is used in the program, it is not instantiated, and does not require a definition.
第(3)
行有效; sptr
指成员sptr
,与this->sptr
.
作用相同
When a non-static class member is used in any of the contexts where the this keyword is allowed (non-static member function bodies, member initializer lists, default member initializers), the implicit this->
is automatically added before the name, resulting in a member access expression (which, if the member is a virtual member function, results in a virtual function call).
你会相信这个编译的原因是因为这里没有真正编译吗?
显示的代码定义了一个模板。
模板在实例化 class 之前不会变成 "real"。只有在那个时候,编译器才会更仔细地查看模板,并试图弄清楚它在做什么。
当然,在定义模板时,编译器会半心半意地尝试解析模板,但仅勉强足以让自己确信模板由一些看似合理的 C++ 代码组成。
如果您在显示的代码中添加一些额外的行,您将得到您想要的编译错误:
class X {};
void foo()
{
sptr_wrapper<X> x;
boost::shared_ptr<X> y;
x.set_from_sptr(y);
}
这会产生您正在查找的编译错误:
t.C:27:14: error: request for member ‘sptr’ in ‘(sptr_wrapper<X>*)this’, which is of pointer type ‘sptr_wrapper<X>*’ (maybe you meant to use ‘->’ ?)
27 | this.sptr = sptr; // (2)
注意仅仅实例化
sptr_wrapper<X> x;
还不够。在 C++ 编译器眼中它变成 "real" 之前,你必须全力以赴并调用有问题的方法,并且它会阻塞它。
的确,我完全可以想到 "this.foo" 可能是有效 C++ 代码的任何情况,但我确信在构成当前 C++ 标准的 2000 页中的某处,确切的细节正在发生的事情以一种非常迂腐的方式被阐明。
并且您可能会考虑在编译器的错误跟踪器中添加一个注释,这是一个功能请求,让您的编译器在看到类似这样的情况时提前发出友好的警告。
行 (2)
和 (3)
如何在以下 C++ class 中编译,鉴于 this
是一个指针,所以应该需要 ->
访问字段的符号(如 (1)
行所示)? (Source)
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
template <typename T>
class sptr_wrapper
{
private:
boost::shared_ptr<T> sptr;
public:
template <typename ...ARGS>
explicit sptr_wrapper(ARGS... a)
{
this->sptr = boost::make_shared<T>(a...);
}
explicit sptr_wrapper(boost::shared_ptr<T> sptr)
{
this->sptr = sptr; // (1)
}
virtual ~sptr_wrapper() noexcept = default;
void set_from_sptr(boost::shared_ptr<T> sptr)
{
this.sptr = sptr; // (2)
}
boost::shared_ptr<T> get_sptr() const
{
return sptr; // (3)
}
};
行(2)
无效。正如你所说,this
是一个指针,我们需要使用->
而不是.
作为class template的成员,sptr_wrapper::set_from_sptr
在使用之前不需要实例化。所以你可以添加一些代码来尝试调用它,然后你可能会如你所料得到编译错误。
This applies to the members of the class template: unless the member is used in the program, it is not instantiated, and does not require a definition.
第(3)
行有效; sptr
指成员sptr
,与this->sptr
.
When a non-static class member is used in any of the contexts where the this keyword is allowed (non-static member function bodies, member initializer lists, default member initializers), the implicit
this->
is automatically added before the name, resulting in a member access expression (which, if the member is a virtual member function, results in a virtual function call).
你会相信这个编译的原因是因为这里没有真正编译吗?
显示的代码定义了一个模板。
模板在实例化 class 之前不会变成 "real"。只有在那个时候,编译器才会更仔细地查看模板,并试图弄清楚它在做什么。
当然,在定义模板时,编译器会半心半意地尝试解析模板,但仅勉强足以让自己确信模板由一些看似合理的 C++ 代码组成。
如果您在显示的代码中添加一些额外的行,您将得到您想要的编译错误:
class X {};
void foo()
{
sptr_wrapper<X> x;
boost::shared_ptr<X> y;
x.set_from_sptr(y);
}
这会产生您正在查找的编译错误:
t.C:27:14: error: request for member ‘sptr’ in ‘(sptr_wrapper<X>*)this’, which is of pointer type ‘sptr_wrapper<X>*’ (maybe you meant to use ‘->’ ?)
27 | this.sptr = sptr; // (2)
注意仅仅实例化
sptr_wrapper<X> x;
还不够。在 C++ 编译器眼中它变成 "real" 之前,你必须全力以赴并调用有问题的方法,并且它会阻塞它。
的确,我完全可以想到 "this.foo" 可能是有效 C++ 代码的任何情况,但我确信在构成当前 C++ 标准的 2000 页中的某处,确切的细节正在发生的事情以一种非常迂腐的方式被阐明。
并且您可能会考虑在编译器的错误跟踪器中添加一个注释,这是一个功能请求,让您的编译器在看到类似这样的情况时提前发出友好的警告。