我有一个派生自接口的类和一个派生类的友元类。我想访问实例化为接口的派生类的成员。它看起来像这样:
接口:
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;
}
- 由子项覆盖且纯的方法应该是虚拟的。
- 如果每个类(子)
Interface
,变量int mem
应该在接口中受到保护。 现在工作正常,就像你想要的那样。 - 添加吸气剂
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 个选项。
使用
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
,可能会降低您的应用程序速度。
将
a
存储在A*
中,这可能是您从一开始就打算做的事情...class B { // ... private: A* a; // now a->A::mem is visible. };
由于您在 B 的构造函数中显式调用new A
,我认为选项 2 更适合您的情况。