访问使用接口实例化的 class 的私有成员

Access private members of a class instantiated using interface

我有一个从接口派生的 class 和派生的 class 的朋友 class。我想访问实例化为接口的派生 class 的成员。它看起来像这样:

接口:

class AInterface
{
public:
   virtual ~AInterface() = default;
   virtual void set(int a) = 0;
};

派生 class A 和朋友 class B:

class B;
class A : public AInterface
{
public:
   ~A() override {}
   void set(int a) override
   {
      mem = a;
   }
private:
   friend class B;

   int mem = 0;
};

class乙:

class B
{
public:
   B() 
   {
     a = new A();
     a->set(3);
   }

   int get_a()
   {
      // Access mem since it's a friend class
      return a->mem;
   }

private:
    AInterface *a;
}

主要内容:

int main()
{
    B *b = new B();
    std::cout << b->get_a() << std::endl;
    return 0;
}

程序无法编译,提示 AInterface 没有名为 'mem' 的成员。 我是否需要在界面中使用 getter 函数并在 A 中实现它,或者是否有任何其他方法可以做到这一点?

现在工作

#include <iostream>
using namespace std;


class AInterface
{
public:
    virtual ~AInterface() = default;
    int getMem() { return mem; }
    virtual void set(int a) = 0;
protected:
    int mem = 0;
};

class A : public AInterface
{
public:
    ~A() override {}
    void set(int a) override
    {
        mem = a;
    }


};

class B
{
public:
    B()
    {
         a = new A{};
        a->set(3);
    }

    int get_a()
    {
        // Access mem since it's a friend class
        return a->getMem();
    }

private:
    AInterface *a;
};
int main()
{
    B *b = new B();
    std::cout << b->get_a() << std::endl;
    return 0;
}
  1. 被child覆盖的纯方法,应该是虚拟的。
  2. 如果每个class (child) Interface,变量int mem应该在接口中被保护。 现在工作正常,如你所愿。
  3. 添加gettergetMem()

版本 friend

#include <iostream>
using namespace std;


class AInterface
{
public:
    virtual ~AInterface() = default;
    virtual void set(int a) = 0;
protected:
    friend class B;
    int mem = 0;
};

class A : public AInterface
{
public:
    ~A() override {}
    void set(int a) override
    {
        mem = a;
    }


};

class B
{
public:
    B()
    {
         a = new A{};
        a->set(3);
    }

    int get_a()
    {
        // Access mem since it's a friend class
        return a->mem;
    }

private:
    AInterface *a;
};
int main()
{
    B *b = new B();
    std::cout << b->get_a() << std::endl;
    return 0;
}

在你的class B.

class B
{
  //...
   int get_a()
   {
      return a->mem;   // but a is a AInterface*  !!!
   }

private:
    AInterface *a;     // That's not an A*, but an AInterface*
};

你有2个选项。

  1. 使用dynamic_cast<>

     int B::get_a()
     {
         A* p = dynamic_cast<A*>(a);
         if (p)
           return p->mem;  
         // a is not an A*, it's another AInterface*-type object !!!  
                                       // What should you do?
         throw something_or_other();   // throw?
         return -1;                    // return an error code?
       }
       // or maybe add..  so you can check for errors before calling get_a()
       A* B::get_A_ptr() const 
       { 
          return dynamic_cast<A*>(a); 
       }
    

dynamic_cast 工作正常,但如果您需要频繁读取 a->mem.

可能会减慢您的应用程序
  1. a 存储在 A* 中,这可能是您从一开始就打算做的...

    class B
    {
      // ...
    private:
      A* a;    // now a->A::mem is visible.
    };
    

由于您在 B 的构造函数中显式调用 new A,我认为选项 2 更适合您的情况。