访问使用接口实例化的 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;
}
- 被child覆盖的纯方法,应该是虚拟的。
- 如果每个class (child)
Interface
,变量int mem
应该在接口中被保护。
现在工作正常,如你所愿。
- 添加getter
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;
}
在你的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个选项。
使用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 更适合您的情况。
我有一个从接口派生的 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;
}
- 被child覆盖的纯方法,应该是虚拟的。
- 如果每个class (child)
Interface
,变量int mem
应该在接口中被保护。 现在工作正常,如你所愿。 - 添加getter
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;
}
在你的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个选项。
使用
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 更适合您的情况。