假设我有两个班级
class A{
/*with some attributes and methods*/
};
class B{
/*with some other attributes and methods*/
};
我想有两件似乎相互排斥的事情......
B
成为A
的孩子。所以我想声明class B:public A
。 但如果我这样做,B
只包含"一套"属性A
class B:public A{
/*with some attributes and methods*/
};
B
有N
个A
个不同的实例(数组)。但如果我这样做,B
并不知道A
中包含的方法,而且我放弃了我需要的类层次结构。
class B{
/*with some attributes and methods*/
private:
A* a;
unsigned int N; /*number of instances A*/
};
我当然可以将两者合并,但这似乎不是一个好主意,因为B
将包含N+1
个实例A
。我的意思是+1
,A
中包含的所有参数都将在B
中继承。
是否有一种优雅的方式来结合我的两个要求?
答案 0 :(得分:3)
您的要求中有两个问题。
他们彼此并不相互排斥。事实上,Composite Pattern是在子类型中使用两者的典型示例。
当你说:
class A
{
};
class B : public A
{
A* aList;
int N;
};
您正在使用经典的复合图案。如果您将名称A
和B
更改为Object
和CompositeObject
,则图片会更清晰。
class Object
{
};
class PrimitiveObject : public Object
{
};
class CompositeObject : public Object
{
Object* objectList;
int N;
};
在此模式中,objectList
中的一个对象可以是CompositeObject
。
答案 1 :(得分:1)
我认为你想要的是
class AInterface
{
public:
virtual void ChangeFoo() = 0;
};
class A : public AInterface
{
public:
virtual void ChangeFoo()
{
}
;
class B : public AInterface
{
public:
virtual void ChangeFoo()
{
for( A a : allAsOwnedBythis())
{
a.ChangeFoo();
}
}
};
因此,您永远不会使用A或B,但AInterface
和A
B
答案 2 :(得分:0)
你可以让B成为A的朋友类,这样你仍然可以访问带有数组的私有成员。
class A {
friend class B;
...
};
class B {
A* a;
int n;
};
答案 3 :(得分:0)
有一种优雅的解决方法 - 处理非叶类,例如A
和B
,就像它们是抽象的一样(有或没有实际制作他们抽象)。
以下是我的意思 - 将class C
与A
和B
必须共有的部分一起制作。然后分别继承这两个类,如下所示:
class C {
// The common parts
};
class A : public C {
// Parts specific to A
};
class B : public C {
// Parts specific to B
private:
A* a; // Depending on your design, this could be C*, not A*
unsigned int N;
};
这样,您的class B
可以继承与class A
共享所需的部分,而不会成为A
的实例,并继承N+1
- { {1}}的属性。