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

Access private members of a class instantiated using interface

本文关键字:成员 实例化 接口 访问      更新时间:2023-10-16

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

接口:

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

派生类 A 与友元类 B:

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

B类:

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. 由子项覆盖且纯的方法应该是虚拟的。
  2. 如果每个类(子)Interface,变量int mem应该在接口中受到保护。 现在工作正常,就像你想要的那样。
  3. 添加吸气剂getMem()

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;
}

在你的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 更适合您的情况。