因此,我有一个类和继承的类似概念,并且我想以某种优雅的方式做一些被禁止的事情。下面是一个非常简单的代码片段,反映了我想要做的事情:
#include <iostream>
class A{
protected:
int var;
std::vector <double> heavyVar;
public:
A() {var=1;}
virtual ~A() {}
virtual void func() {
std::cout << "Default behavior" << this->var << std::endl;
}
// somewhere along the way, heavyVar is filled with a lot of stuff
};
class B: public A{
protected:
A* myA;
public:
B(A &a) : A() {
this->myA = &a;
this->var = this->myA->var;
// copy some simple data, e.g. flags
// but don't copy a heavy vector variable
}
virtual ~B() {}
virtual void func() {
this->myA->func();
std::cout << "This class is a decorator interface only" << std::endl;
}
};
class C: public B{
private:
int lotsOfCalc(const std::vector <double> &hv){
// do some calculations with the vector contents
}
public:
C(A &a) : B(a) {
// the actual decorator
}
virtual ~C() {}
virtual void func() {
B::func(); // base functionality
int heavyCalc = lotsOfCalc(this->myA->heavyVar); // illegal
// here, I actually access a heavy object (not int), and thus
// would not like to copy it
std::cout << "Expanded functionality " << heavyCalc << std::endl;
}
};
int main(void){
A a;
B b(a);
C c(a);
a.func();
b.func();
c.func();
return 0;
}
这样做的原因是我实际上正在尝试实现装饰器模式(
class B
具有我想要装饰的myA
内部变量),但我也想在进行“装饰”计算时使用class A
的某些受保护成员(在class B
及其所有子类中)。因此,这个例子不是一个正确的装饰器示例(甚至不是一个简单的示例)。在这个例子中,我只关注演示问题功能(我想使用但无法使用的功能)。甚至没有使用实现装饰器模式所需的所有类/接口(我没有一个抽象基类接口,由具体基类实例继承,以及一个抽象装饰器接口,用作具体装饰器的超类)。我只提到装饰器来说明上下文(我想要一个A*
指针的原因)。
在这种情况下,我认为将(相当于)int var
公开(甚至编写可公开访问的getter)没有太多意义,原因如下:
- 更明显的一个原因是,我不希望用户直接使用信息(我有一些函数返回与/或写在我的
protected
变量中的相关信息,但不包括变量值本身) - 在我的情况下,
protected
变量比int
更难以复制(它是一个2D的std::vector
,包含double
),将其复制到派生类的实例中会浪费时间和内存。
目前,我有两种不同的方法来让我的代码做我想要它做的事情,但我都不喜欢,我正在寻找一个适用于执行此类操作的C++
概念(我不可能是第一个需要这种行为的人)。
我目前所拥有的及其原因:
1. 将所有(相关的)继承类声明为基类的友元:
class A{
....
friend class B;
friend class C;
};
我不喜欢这个解决方案,因为每次我写一个新的子类时就需要修改我的基类,这正是我想要避免的。 (我只想在系统的主模块中使用“A”接口。)
2. 将
A*
指针转换为继承类的指针并使用它工作。void B::func(){
B *uglyHack = static_cast<B*>(myA);
std::cout << uglyHack->var + 1 << std::endl;
}
变量名对我的情感使用这种方法提出了明显的建议,但这是我现在正在使用的方法。由于我设计了这些类,我知道如何小心谨慎地使用仅实际实现在
class A
中的东西,同时将其视为 class B
。但是,如果其他人继续开展我的项目工作,他可能不太熟悉代码。此外,将变量指针强制转换为我非常清楚它不是的东西,让我感到纯粹的邪恶。我试图尽可能保持这个项目的代码整洁和设计良好,因此如果有人对不需要每隔一段时间修改基础类或使用邪恶概念的解决方案有任何建议,我会非常感激。