如何在继承的类成员函数中访问基类成员的地址

How to access the address of base class member in inherited class member functions?

本文关键字:成员 访问 地址 基类 函数 继承      更新时间:2023-10-16

我最近进入了c++中类、继承和模板的整个世界。但我被困住了。请给我一个解决这个问题的方法。

#include <iostream>
using namespace std;
template <typename type>
class a
{
protected:
  type *b;
};
template <typename type>
class p : public a<type>
{
public:
  void f()
  {
    type **q = &a<type>::b;
    cout << *q << endl; // some other code in reality related to (*q)
  }
};
int main()
{
  p<int> obj;
  obj.f();
  return 0;
}

但结果是失败的:

x.cpp: In instantiation of ‘void p<type>::f() [with type = int]’:
x.cpp:26:9:   required from here
x.cpp:9:9: error: ‘int* a<int>::b’ is protected
   type *b;
         ^
x.cpp:18:16: error: within this context
     type **q = &a<type>::b;
                ^
x.cpp:18:26: error: cannot convert ‘int* a<int>::*’ to ‘int**’ in initialization
     type **q = &a<type>::b;
                          ^

我将type **q = &a<type>::b;转换为type* a<type>::* q = &a<type>::b;。然后我得到了一个额外的错误:

x.cpp: In instantiation of ‘void p<type>::f() [with type = int]’:
x.cpp:26:9:   required from here
x.cpp:9:9: error: ‘int* a<int>::b’ is protected
   type *b;
         ^
x.cpp:18:26: error: within this context
     type* a<type>::* q = &a<type>::b;
                          ^
x.cpp:19:13: error: invalid use of unary ‘*’ on pointer to member
     cout << *q;
             ^

因此,我将bprotected:转换为class apublic:成员。但这也给了我一个错误:

x.cpp: In instantiation of ‘void p<type>::f() [with type = int]’:
x.cpp:26:9:   required from here
x.cpp:19:13: error: invalid use of unary ‘*’ on pointer to member
     cout << *q;
             ^

现在我不能执行进一步的修改。我很想知道原始代码是否篡改了类被保护的特征

您仍然可以使用protected: type *b;,如果您在代码中更改以下行:

type **q = &a<type>::b;  // `protected: b` is not accessible in this context

type **q = &(this->b);  // we make sure that `protected: b` is accessed here

在这种情况下,您实际上将b视为继承的protected成员。


为什么使用this访问基类?
reference:在模板化的派生类中,为什么需要用"this->"来限定基类成员名?在成员函数内部?


另一种方式

最初由@Quentin链接,下面的帖子说明了简单指针和指向成员的指针的区别:
Pointer-to-member困惑

所以,在你最初的问题中,实际上你试图通过以下语法获得一个指向成员变量的指针:

&a<type>::b  ==> int* a<int>::*

你可能想要&(a<type>::b),这将导致简单的int*
这是一个笔记本上的例子,展示了在正确的地方放括号的好处!: -)