从基类派生类中 C++ 向量的可访问性
Posted
技术标签:
【中文标题】从基类派生类中 C++ 向量的可访问性【英文标题】:Accessibility of C++ vector in derived class from base class 【发布时间】:2014-03-07 09:34:17 【问题描述】:我的场景在下面的例子中得到了简化:
#include <iostream>
#include <vector>
using namespace std;
class C;
class A
protected:
C * cPointer;
A();
virtual void updateList() = 0;
void callFunc();
;
class B : public A
private:
vector<int> list;
void updateList();
public:
void callFromA();
;
class C
friend class A;
friend class B; // I want to get rid off this declaration
private:
int sum;
void set_sum( int val );
public:
static C * getCPointer();
;
A::A()
cPointer = C::getCPointer();
void A::callFunc()
updateList();
void B::updateList()
list.push_back(2);
list.push_back(4);
int s = 0;
for( unsigned int i=0; i<list.size(); i++ )
s += list[i];
cPointer->set_sum(s);
void B::callFromA()
callFunc();
void C::set_sum( int val )
sum = val;
cout << "Sum at C is: " << sum << endl;
C * C::getCPointer()
static C cPointer;
return & cPointer;
int main( int argc, char ** argv)
B b;
b.callFromA();
return 0;
这个例子运行良好。但我想摆脱 C 类中的“朋友 B 类”声明并实现类似的功能。其实我想要以下任何一种:
C::set_sum() 从 B::updateList() 的可访问性,如果没有 C 类中的“朋友类 B”声明,这是不可能的。
A::callFunc() 中 B::list 的可访问性,我可以将逻辑从 B::updateList 推送到 A::callFunc(),这基本上意味着能够访问派生类中的列表基类。这样,由于 C 类中的“friend class A”声明,我将能够访问 A::callFunc() 中的 set_sum()。
在不涉及重大设计更改的情况下实现这一点的任何想法都是可取的!
谢谢!
【问题讨论】:
你是从B::callFromA()
调用全局函数callFunc()
吗?那么它在哪里呢?
这里的问题可能是您将拥有许多来自基类A
的派生类,并且您不想将所有这些类都列为C
的朋友。为了帮助实现这一点,您可以只将基类A
设为C
的朋友,并且可以将受保护的set_sum()
方法放入A
中,所有派生类都可以调用该方法,所有这些A::set_sum
都可以正在将呼叫转接到C::set_sum
。这个转发函数调用将被编译器优化掉。
@barakmanos: callFunc() 作用于 A 并从 B::callFromA() 调用,因为 B 派生自 A。
@Code Warrior:是的,我现在明白了;谢谢。
@pasztorpisti:这看起来是一个简单而有效的解决方案..谢谢!
【参考方案1】:
我不确定我是否了解您的所有限制,但也许这对您更有效。基本上,您可以使用虚函数从A
访问B::list
。我已经注释了代码中的更改。
#include <iostream>
#include <vector>
using namespace std;
class A;
class C
friend class A;
private:
int sum;
void set_sum(int val);
public:
static C * getCPointer();
;
class A
protected:
C * cPointer;
A();
virtual int getS() = 0; // virtual function to calculate data from vector in derived class B
virtual void updateList()
cPointer->set_sum(getS()); // A is friend of C, so you can access B data from A
void callFunc();
;
class B : public A
private:
vector<int> list;
void updateList();
int getS() // concrete implementation to access vector data
int s = 0;
for (unsigned int i = 0; i < list.size(); i++)
s += list[i];
return s;
public:
void callFromA();
;
A::A()
cPointer = C::getCPointer();
void A::callFunc()
updateList();
void B::updateList()
list.push_back(2);
list.push_back(4);
A::updateList(); // Call to super implementation
void B::callFromA()
callFunc();
void C::set_sum(int val)
sum = val;
cout << "Sum at C is: " << sum << endl;
C * C::getCPointer()
static C cPointer;
return &cPointer;
int main(int argc, char ** argv)
B b;
b.callFromA();
return 0;
【讨论】:
感谢您的评论..我不允许将其设为公共功能,因为这是内部功能,不应暴露给用户..但是,我们只能在其中添加一些新内容受保护/私有范围!【参考方案2】:您不能在基类中访问派生类的成员,句号。手头的对象可能是基类,甚至是完全不相关的派生类,保证“有趣”的连续性。任何要求这样做的设计都被严重破坏,需要重新考虑。
您可以将想要这样做的基类的成员函数设为虚拟,并在派生类中重新定义它以执行您想要的任何变态。同时,基类的纯洁成员可以拒绝被调用,以理智的方式发出错误信号。这样您就可以保证不会发生任何不愉快的事情。
【讨论】:
以上是关于从基类派生类中 C++ 向量的可访问性的主要内容,如果未能解决你的问题,请参考以下文章