- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想了解装饰器模式是如何工作的,以及我可以在多大程度上“扩展”它以满足我的需要。正在关注this例如,我有扩展类 XYZ。存在派生类“KLM”(来自 XYZ)
具体来说,即使我有一个装饰器模式,派生的装饰器类“KLM”有一些功能在它们的任何基类“XYZ”、“D”、“I”或“A”中都没有出现。
所以虽然通常我会将一个对象实例化为
I * inKLM = new L( new M( new K( new A )));
这将不允许我访问 K::doVirtR()
、 L::doVirtS() 和 M::doVirtT() 函数(参见下面的代码)。要访问这些,我需要使用 dynamic_cast
将 inKLM 指针向下转换为每个类“KLM”。
问题是我只设法对上面表达式中最左边的 new
执行此操作。我读到需要维护多态性才能使动态转换工作,所以我尝试在所有函数中都有一个虚拟析构函数。除了“外部”new
操作(在本例中为“L”类的对象)之外,我仍然无法让动态转换工作。
请看这段代码。我怎样才能不仅使“LinKLM”,而且使“MinKLM”和“KinKLM”在 dynamic_casting 中取得成功?
#include <iostream>
#include <list>
using namespace std;
class D; //decorator base
struct I { //interface (for both Base and DecoratorBase
I(){
cout << "\n| I::ctor ";
}
virtual ~I(){
cout << "I::dtor |" ;
}
virtual void do_it() = 0;
virtual void regDecorator(D* decorator) = 0;
virtual void train() = 0;
virtual void et() = 0;
};
class D: public I { //DecoratorBase : has same-named fns as Base (must be exported on I) and calls upon them.
public:
D(I * inner) : m_wrappee(inner) {
cout << "D::ctor ";
regDecorator(this);
}
virtual ~D() {
cout << "D::dtor ";
delete m_wrappee;
}
void do_it() {
m_wrappee->do_it();
}
virtual void et() {
cout << "filling in for lack of et() in derived class\n";
} //almost pure virtual, just not implemented in all derived classes
void train(){
m_wrappee->train();
}
private:
void regDecorator(D* decorator){
m_wrappee->regDecorator(decorator);
}
I * m_wrappee;
};
class A: public I { //Base has all the basic functionality
public:
A() {
cout << "A::ctor " ;
decList.clear();
}
~A() {
cout << "A::dtor |" ;
}
void do_it() {
cout << 'A';
}
void train(){
et();
}
void regDecorator(D* decorator)
{
if (decorator) {
cout << "reg=" << decorator << " ";
decList.push_back(decorator);
}
else
cout << "dec is null!" <<endl;
}
private:
void et()
{
//size_t counter=0;
list<D*>::iterator it;
for( it=decList.begin(); it != decList.end(); it++ )
{
//if ( (*it)->et() )
(*it)->et();
//else
// cout << "couldnt et cnt=" << counter << endl;
//counter++;
}
}
std::list<D*> decList;
};
class X: public D { //DerivedDecoratorX ..
public:
X(I *core): D(core){
cout << "X::ctor ";
}
virtual ~X() {
cout << "X::dtor ";
}
void do_it() {
D::do_it();
cout << 'X';
}
void doX() {
cout << "doX" << endl;
}
protected:
virtual void doVirtR() = 0;
private:
void et(){
cout << "X::et" <<endl;
}
};
class K: public X {
public:
K(I * core):X(core) {
cout << "K::ctor " ;
}
virtual ~K() {
cout << "K::dtor ";
}
void doVirtR(){
cout << "doVirtK" <<endl;
}
};
class Y: public D {
public:
Y(I *core): D(core){
cout << "Y::ctor ";
}
virtual ~Y() {
cout << "Y::dtor ";
}
/*void et(){
cout << "Y::et" <<endl;
}*/
void do_it() {
D::do_it();
cout << 'Y';
}
void doY() {
cout << "doY" << endl;
}
protected:
virtual void doVirtS() = 0;
};
class L: public Y{
public:
L(I * core):Y(core) {
cout << "L::ctor ";
}
virtual ~L() {
cout << "L::dtor ";
}
void doVirtS(){
cout << "doVirtL" <<endl;
}
};
class Z: public D {
public:
Z(I *core): D(core){
cout << "Z::ctor ";
}
virtual ~Z() {
cout << "Z::dtor ";
}
void et(){
cout << "Z::et" <<endl;
}
void do_it() {
D::do_it();
cout << 'Z';
}
void doZ() {
cout << "doZ" << endl;
}
virtual void doVirtT() = 0;
};
class M: public Z{
public:
M(I * core):Z(core) { //must add D(core) here explicitly because of virtual inheritance in M's base class (Z).
cout << "M::ctor " ;
}
virtual ~M() {
cout << "M::dtor ";
}
void doVirtT(){
cout << "doVirtM" <<endl;
}
};
int main(void) //testing dynamic casting
{
I * inKLM = new L( new M( new K( new A )));
L * LinKLM = dynamic_cast<L *>( inKLM);
M * MinKLM = dynamic_cast<M *>( inKLM);
K * KinKLM = dynamic_cast<K *>( inKLM);
cout << endl;
if ( ! MinKLM ) cout << "null MinKLM!" << endl;
if ( ! LinKLM ) cout << "null LinKLM!" << endl;
if ( ! KinKLM ) cout << "null KinKLM!" << endl;
//KinKLM->doVirtR();
//LinKLM->doVirtS();
//MinKLM->doVirtT();
//LinKLM->D::train();
//KinKLM->do_it();
//MinKLM->doZ();
delete inKLM;
cout << endl;
return 0;
}
最佳答案
如果您需要访问某些内部类中独有的功能,您最好(取决于特定问题)尝试混合类。基本思想是让一个模板类继承它的模板参数。我简化了下面的类,但原理很清楚:
#include <iostream>
// your base class
class I {
public:
virtual void do_it() {}
};
// a decorator
template <class Base>
class T1 : public Base {
public:
void do_it() {
std::cout << "T1" << std::endl;
Base::do_it();
}
void unique_in_T1() {
std::cout << "Unique in T1" << std::endl;
}
};
// another decorator
template <class Base>
class T2 : public Base {
public:
void do_it() {
std::cout << "T2" << std::endl;
Base::do_it();
}
void unique_in_T2() {
std::cout << "Unique in T2" << std::endl;
}
};
// yet another decorator
template <class Base>
class T3 : public Base {
public:
void do_it() {
std::cout << "T3" << std::endl;
Base::do_it();
}
void unique_in_T3() {
std::cout << "Unique in T3" << std::endl;
}
};
int main(int argc, const char * argv[]) {
T3<T2<T1<I>>> my_object1;
my_object1.do_it();
my_object1.unique_in_T2();
T1<T3<I>> my_object2;
my_object2.do_it();
my_object2.unique_in_T3();
return 0;
}
您的类 D
不再需要了。该类的主要目的是包装实际完成工作的对象,同时维护I
的接口(interface)。对于 mixin 类,不再有包装,因为它已被继承取代,因此不需要 D
类。
Here是阅读更多内容的链接。
关于c++ dynamic_cast 装饰器实例化失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39312070/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!