问题描述
我对 C++ 编译器如何处理虚函数中的“this”指针感到困惑,我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <iostream>
using namespace std;
class A {
public:
void print_A(void) {
cout << "A::THIS = " << this << endl;
return;
}
int a;
virtual ~A(void) {
return;
}
};
class B {
public:
virtual void print(void) {
cout << "B::THIS = " << this << endl;
return;
}
int b;
};
class C: public A,public B {
public:
void print(void) {
cout << "C::THIS = " << this << endl;
return;
}
int c;
};
class D {
public:
int d;
virtual ~D(void) {
return;
}
};
class E: public D,public C {
public:
int e;
virtual ~E(void) {
return;
}
};
void global_print(B *pb) {
cout << "pb = " << pb << endl;
pb->print();
return;
}
int main(int argc,char *argv[]) {
E e;
A *pa = &e;
B *pb = &e;
C *pc = &e;
D *pd = &e;
E *pe = &e;
cout << "pa = " << pa << endl;
cout << "pb = " << pb << endl;
cout << "pc = " << pc << endl;
cout << "pd = " << pd << endl;
cout << "pe = " << pe << endl;
pb->print();
pc->print();
pe->print();
global_print(&e);
return 0;
这是在我的 linux 中用 g++ 编译的结果:
pa = 0x7ffc1e7c7a80
pb = 0x7ffc1e7c7a90
pc = 0x7ffc1e7c7a80
pd = 0x7ffc1e7c7a70
pe = 0x7ffc1e7c7a70
C::THIS = 0x7ffc1e7c7a80
C::THIS = 0x7ffc1e7c7a80
C::THIS = 0x7ffc1e7c7a80
pb = 0x7ffc1e7c7a90
C::THIS = 0x7ffc1e7c7a80
我无法理解我将 &e
发送到 global_print
而 pb
中的 global_print
等于 0x7ffc1e7c7a90
。然后我调用 pb->print()
,this pointer
中的 global_print
是 0x7ffc1e7c7a80
,它等于 pc
。貌似pb->print()
把B类转化为C类,但是B类是C类的父类,怎么转化?
虽然pb可以通过虚函数得到C::print
的地址,但只是一个地址信息不足,需要将B类转换为C类,那么程序如何知道需要在运行时将 B 类转换为 C 类?
非常感谢!祝你有美好的一天!
解决方法
#include<iostream>
class D
{
public:
D() {
std::cout << "This is constructor for D class." << std::endl;
};
~D() {
std::cout << "This is destructor for D class." << std::endl;
};
protected:
int variable = 123456;
};
class B :
virtual public D
{
public:
B() {
std::cout << "This is constructor for B class." << std::endl;
};
~B() {
std::cout << "This is destructor for B class." << std::endl;
};
private:
};
class C :
virtual public D
{
public:
C() {
std::cout << "This is constructor for C class." << std::endl;
};
~C() {
std::cout << "This is destructor for C class." << std::endl;
};
private:
};
class A :
public B,public C
{
public:
A() {
std::cout << "This is constructor for A class." << std::endl;
};
~A() {
std::cout << "This is destructor for A class." << std::endl;
};
void function() {
std::cout << "Variable: " << variable << std::endl;
}
private:
};
int main() {
A a;
std::cout << std::endl;
a.function();
std::cout << std::endl;
return 0;
}
编译器不知道哪个类的变量或方法必须继承。为此,我们使用 virtual 关键字。由于virtual关键字,我们告诉编译器只继承一个成员。
class B : virtual public D
......
class C : virtual public D
......
尽可能避免多重继承是必要的!
代码输出:
This is constructor for D class.
This is constructor for B class.
This is constructor for C class.
This is constructor for A class.
Variable: 123456
This is destructor for A class.
This is destructor for C class.
This is destructor for B class.
This is destructor for D class.