c++设计:减少深层类层次结构中的耦合
c++ design: reducing coupling in a deep class hierarchy
请考虑这个类层次结构:
#include <iostream>
struct Base
{
Base(int arg1, int arg2, int arg3, int arg4)
{
std::cout << "Base::Base:" << arg1 << "," << arg2 << "," << arg3 << "," << arg4 << std::endl;
}
void BaseDoWork()
{
std::cout << "Base::BaseDoWork" << std::endl;
}
};
struct Derived1:public Base
{
Derived1(int arg1, int arg2, int arg3, int arg4):Base(arg1, arg2, arg3, arg4){}
void DerivedDoWork()
{
BaseDoWork();
}
};
struct Derived2:public Derived1
{
Derived2(int arg1, int arg2, int arg3, int arg4):Derived1(arg1, arg2, arg3, arg4){}
};
int main(int argc, char *argv[])
{
Derived2 myDerived2(1,2,3,4);
myDerived2.DerivedDoWork();
return 0;
}
Derived1类具有比我希望的更多的耦合性:它必须知道如何构造"Base"类。在深层层次结构中,这意味着在类层次结构中一直传播"Base"类构造函数的参数。更改"Base"类构造函数需要更改所有派生类。
我对这个类层次结构的目标是:
Derived1期望基类中有一个BaseDoWork()方法,但不需要知道如何构造基类。
Derived2知道如何构造"Base"类。
理想情况下,我想让Derived1成为一个模板,接受任何带有可访问的"BaseDoWork()"方法的基类,如下所示:
template <T> struct Derived1:public T
{
void DerivedDoWork()
{
BaseDoWork();
}
};
但是,如果我将上面的模板实例化为Derived1<Base>
,如果不向Derived1添加"Base"构造函数参数的知识,我就看不到如何构造"Base"类。
假设这是真实的层次结构,如果Derived1
是Base
派生的类,则必须知道如何构造父类(Base
)。
正如我所理解的,也许我错了,如果Derived1
实际上不是Base
派生的(子)类,并且只需要知道它的接口,那么就不需要知道如何构造Base
实例。因此,您可以定义Derived1如下:
struct Derived1
{
Derived1(int arg1, int arg2, int arg3, int arg4)
{}
.....
};
只有Base
派生类需要知道如何构造Base
:
struct Derived2 : public Base
{
Derived2(int arg1, int arg2, int arg3, int arg4) :
Base(arg1, arg2, arg3, arg4)
{}
.....
};
现在,如果Derived2
真的是Derived1
的子级,那么必须知道如何创建它的父级。以前的代码变为:
struct Derived2 : public Base, public Derived1
{
Derived2(int arg1, int arg2, int arg3, int arg4) :
Base(arg1, arg2, arg3, arg4),
Derived1(arg1, arg2, arg3, arg4)
{}
.....
};
如果必须使用Derived1
中的Base::BaseDoWork()
方法,则可以按如下方式定义类:
struct Base
{
Base(int arg1, int arg2, int arg3, int arg4)
{
std::cout << "Base::Base:" << arg1 << "," << arg2 << "," << arg3 << "," << arg4 << std::endl;
}
virtual void BaseDoWork()
{
std::cout << "Base::BaseDoWork" << std::endl;
}
};
struct Derived1
{
Derived1(int arg1, int arg2, int arg3, int arg4)
{}
template <typename T>
void DerivedDoWork(T & base) // only knows T interface
{
base.BaseDoWork();
}
};
struct Derived2 : public Base, public Derived1
{
Derived2(int arg1, int arg2, int arg3, int arg4) :
Base(arg1, arg2, arg3, arg4),
Derived1(arg1, arg2, arg3, arg4)
{}
virtual void DerivedDoWork()
{
Derived1::DerivedDoWork<Base>(*(static_cast<Base *>(this)));
}
};
Main保持不变。
可能您需要查看此层次结构。
当public
从Base
继承Derived1
时,结果是Derived1
已经知道如何构造Base
,所以如果你想让Derived1
不知道如何构造Base
,也许最好不要从Base
继承它?相反,将Base
分离为某种表演者。
考虑一下这段代码,我并不认为这是解决方案,但也许它会把你推向其他想法(类的名称相同):
#include <iostream>
struct Base
{
Base()
{
std::cout << "Base::Base:" << std::endl;
}
Base(int arg1, int arg2, int arg3, int arg4)
{
std::cout << "Base::Base:" << arg1 << "," << arg2 << "," << arg3 << "," << arg4 << std::endl;
}
void DoWork()
{
std::cout << "Base::BaseDoWork" << std::endl;
}
};
template <typename T>
struct Derived1
{
T object;
Derived1(T obj){ object = obj; }
void DerivedDoWork()
{
object.DoWork();
}
};
template <typename T>
struct Derived2 : public Derived1<T>
{
Derived2(int arg1, int arg2, int arg3, int arg4) : Derived1( T(arg1, arg2, arg3, arg4))
{ }
};
int main(int argc, char *argv[])
{
Derived2<Base> myDerived2(1,2,3,4);
myDerived2.DerivedDoWork();
return 0;
}
- 如何重构类层次结构以避免菱形问题
- C++ 中模板化类型的类层次结构
- 为什么不同类型层次结构的指针之间的dynamic_cast定义得很好?
- 继承层次结构并将元素添加到向量
- C++ 类层次结构中的"对齐"是什么意思?
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 类层次结构中的运算符重载
- 如何在层次结构中实现运算符使用?
- 反向层次结构中的可变参数模板参数
- 如何在继承层次结构中调用具有默认参数的构造函数?
- C++ 提升 - 包含类层次结构对象的类的序列化
- 在C++继承层次结构时提取实现者
- 在C++中将类实例添加到对象层次结构中的问题
- 确定大层次结构中基本指针的实际类型,无需dynamic_cast
- 在继承层次结构中复制和移动
- 模板冲突的类型-但类型应该是相同的cfr类层次结构
- 删除父/子窗口层次结构的最佳方法
- 是否可以使一个类成为两个不同层次结构的子类?
- 将静态访问者与静态多态性层次结构相耦合
- c++设计:减少深层类层次结构中的耦合