英文:
How does 'this' keyword in the Base template class of CRTP work?
问题
I understand your request. Here's the translated code:
我一直在研究**CRTP**,但我不理解的是在`main()`函数中,我们创建了一个`Base<Derived>*`类型的对象并调用了`callDerived`方法,为什么'`this`',它是`Base`的一个实例,却拥有`Derived`类的所有信息?我明白`Derived`继承自`Base<Derived>`,但`Derived`只是`Base`的一个模板,但CRTP却像双向继承一样工作:`Derived`继承自`Base`,而`Base`也继承自`Derived`。在这一行中' Base<Derived>* pObjBase = new Base<Derived>();','`Derived`'只是`Base`的一个模板!
我想知道背后发生了什么,以使'`this`'拥有**Derived**的所有信息!
```cpp
#include <iostream>
template <typename T>
class Base {
public:
virtual ~Base() = default;
Base()
{
std::cout << " Base()\n";
}
void callDerived() {
T& refDerived = static_cast<T&>(*this);
refDerived.derivedMethod();
T* pDerived = static_cast<T*>(this);
pDerived->derivedMethod();
//T& obj3 = dynamic_cast<T>(*this); //Error
//T obj4 = dynamic_cast<T>(*this); //Error
//obj3.derivedMethod();
//obj4.derivedMethod();
}
};
class Derived : public Base<Derived> {
public:
Derived() :
Base()
{
std::cout << "Derived() \n";
}
void derivedMethod() {
std::cout << "Derived method gets invoked" << std::endl;
}
};
int main() {
Base<Derived>* pObjBase = new Base<Derived>();
pObjBase ->callDerived(); // 输出:调用Derived方法
delete pObjBase ;
}
英文:
I have been studying about CRTP and what I don't understand is in the main() where we create an object of type Base<Derived>*
and invoke callDerived
, how come 'this
' which is an instance of Base
, has all the information of Derived
class too? I understand Derived inherits from Base<Derived> but 'Derived' is juts template for Base but CRTP works like that is a two-way inheritance : Derived
is derived from Base
and Base
is also derived from Derived
while in this line ' Base<Derived>* pObjBase = new Base<Derived>();' , 'Derived
' is a just template for Base
!
I would like to know what is happening behind the scenes that 'this' has all the information of Derived!
#include <iostream>
template <typename T>
class Base {
public:
virtual ~Base() = default;
Base()
{
std::cout << " Base()\n";
}
void callDerived() {
T& refDerived = static_cast<T&>(*this);
refDerived.derivedMethod();
T* pDerived = static_cast<T*>(this);
pDerived->derivedMethod();
//T& obj3 = dynamic_cast<T>(*this); //Error
//T obj4 = dynamic_cast<T>(*this); //Error
//obj3.derivedMethod();
//obj4.derivedMethod();
}
};
class Derived : public Base<Derived> {
public:
Derived() :
Base()
{
std::cout << "Derived() \n";
}
void derivedMethod() {
std::cout << "Derived method gets invoked" << std::endl;
}
};
int main() {
Base<Derived>* pObjBase = new Base<Derived>();
pObjBase ->callDerived(); // Output: Derived method called
delete pObjBase ;
}
答案1
得分: 2
It works because you have to make sure that T
is the actual type of the object. You don't make a Base<Derived>
object, because that's the wrong T
and it's broken, as you thought. What you're supposed to do is make a Derived
object, which extends from Base<Derived>
, and all is fine.
The reason you successfully got the message Derived method gets invoked
has nothing to do with templates or CRTP. It is simply because this function in the compiled code doesn't even touch the object at all. Chances are good that you can call this function on null pointers, or pointers to completely unrelated things, and it will still print the message. "It seems to work properly" is an allowed kind of undefined behaviour.
英文:
It works because you have to make sure that T
is the actual type of the object. You don't make a Base<Derived>
object, because that's the wrong T
and it's broken, as you thought. What you're supposed to do is make a Derived
object, which extends from Base<Derived>
, and all is fine.
The reason you successfully got the message Derived method gets invoked
has nothing to do with templates or CRTP. It is simply because this function in the compiled code doesn't even touch the object at all. Chances are good that you can call this function on null pointers, or pointers to completely unrelated things, and it will still print the message. "It seems to work properly" is an allowed kind of undefined behaviour.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论