如何在 C++ 中使用智能指针实现接口隔离原则?
How do I implement the Interface Segregation Principle using smart pointers in C++?
我有 Delphi 和 C# 背景,所以我从他们的角度理解接口。我已经做了几年C++,仍然从它的角度学习接口。
在我的应用程序中,我有一种情况需要 class 实现多个接口(即继承多个纯抽象 classes)来指示每个 [=39] 支持的各种行为=].这不完全是 ISP,但足够接近,是同一个问题。
行为接口不相互继承。没有等级制度。
Delphi 和 C# 可以毫不费力地做到这一点,但我正试图弄清楚这是如何在 C++ 中完成的。 (此外,目前,我仅限于 C++11。)
我探索了 dynamic_pointer_cast、static_pointer_cast,但它们需要继承层次结构。
我查看了 reinterpret_pointer_cast,但它在 C++11 中不可用。
我曾尝试使用我的行为接口继承的根接口(类似于 COM 中的 IUnknown 或 Delphi 中的 IInterface),创建继承层次结构,但后来我 运行 陷入菱形问题.
我看到了一些关于将方法添加到基础接口以 return 引用每个行为接口的建议,但这是一种我真的不想要的耦合,因为我可能需要添加其他行为和 class 稍后实施它们的 es。
这是一些我没有编译的代码,显示了我正在尝试做的事情的一个简单示例。
class IBase
{
public:
virtual void DoBaseStuff() = 0;
}
class IBehaviorA
{
public:
virtual void DoBehaviorA() = 0;
}
class IBehaviorB
{
public:
virtual void DoBehaviorB() = 0;
}
class Base : public IBase
{
public:
Base() {}
virtual ~Base() {}
virtual void DoBaseStuff() { /* ... */ }
}
class JustA : public IBase, public IBehaviorA
{
public:
JustA() {}
virtual ~JustA() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorA() { /* ... */ }
}
class JustB : public IBase, public IBehaviorB
{
public:
JustB() {}
virtual ~JustB() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorB() { /* ... */ }
}
class AandB : public IBase, public IBehaviorA, public IBehaviorB
{
public:
AandB() {}
virtual ~AandB() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorA() { /* ... */ }
virtual void DoBehaviorB() { /* ... */ }
}
void ProcessAllBehaviorA(std::vector<std::shared_ptr<IBase>> bases)
{
for (auto& base : bases)
{
std::shared_ptr<IBehaviorA> behaviorA
= SOME_KIND_OF_CAST<IBehaviorA>(base);
if (behaviorA != nullptr)
{
behaviorA->DoBehaviorA();
}
}
}
void main()
{
std::vector<std::shared_ptr<IBase>> bases;
bases.push_back(std::shared_ptr<IBase>(new Base()));
bases.push_back(std::shared_ptr<IBase>(new JustA()));
bases.push_back(std::shared_ptr<IBase>(new JustB()));
bases.push_back(std::shared_ptr<IBase>(new AandB()));
ProcessAllBehaviorA(bases);
}
我想知道在 ProcessAllBehaviorA 方法中 SOME_KIND_OF_CAST 占位符所在的位置要做什么。
我确信我不是第一个尝试这样做的人。
其他人如何在 C++ 中使用智能指针实现接口隔离原则(或类似我的模式)?
I have explored dynamic_pointer_cast, static_pointer_cast but they require an inheritance hierarchy.
您的代码 确实 具有继承层次结构,因此 std::dynamic_pointer_cast
可以正常工作!我已将一些行为添加到您的代码中,它按预期工作。
#include <memory>
#include <vector>
#include <iostream>
class IBase
{
public:
virtual void DoBaseStuff() = 0;
};
class IBehaviorA
{
public:
virtual void DoBehaviorA() = 0;
};
class IBehaviorB
{
public:
virtual void DoBehaviorB() = 0;
};
class Base : public IBase
{
public:
Base() {}
virtual ~Base() {}
virtual void DoBaseStuff() { /* ... */ }
};
class JustA : public IBase, public IBehaviorA
{
public:
JustA() {}
virtual ~JustA() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorA() { std::cout << "I am just A!" << std::endl; }
};
class JustB : public IBase, public IBehaviorB
{
public:
JustB() {}
virtual ~JustB() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorB() { /* ... */ }
};
class AandB : public IBase, public IBehaviorA, public IBehaviorB
{
public:
AandB() {}
virtual ~AandB() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorA() { std::cout << "I am A and B" << std::endl; }
virtual void DoBehaviorB() { /* ... */ }
};
void ProcessAllBehaviorA(std::vector<std::shared_ptr<IBase>> bases)
{
for (auto& base : bases)
{
std::shared_ptr<IBehaviorA> behaviorA
= std::dynamic_pointer_cast<IBehaviorA>(base);
if (behaviorA != nullptr)
{
behaviorA->DoBehaviorA();
}
else {
std::cout << "Requested pointer does not implement A." << std::endl;
}
}
}
void main()
{
std::vector<std::shared_ptr<IBase>> bases;
bases.push_back(std::shared_ptr<IBase>(new Base()));
bases.push_back(std::shared_ptr<IBase>(new JustA()));
bases.push_back(std::shared_ptr<IBase>(new JustB()));
bases.push_back(std::shared_ptr<IBase>(new AandB()));
ProcessAllBehaviorA(bases);
}
输出:
Requested pointer does not implement A.
I am just A!
Requested pointer does not implement A.
I am A and B
顺便说一下,您在 class 定义的末尾漏掉了分号。
我有 Delphi 和 C# 背景,所以我从他们的角度理解接口。我已经做了几年C++,仍然从它的角度学习接口。
在我的应用程序中,我有一种情况需要 class 实现多个接口(即继承多个纯抽象 classes)来指示每个 [=39] 支持的各种行为=].这不完全是 ISP,但足够接近,是同一个问题。
行为接口不相互继承。没有等级制度。
Delphi 和 C# 可以毫不费力地做到这一点,但我正试图弄清楚这是如何在 C++ 中完成的。 (此外,目前,我仅限于 C++11。)
我探索了 dynamic_pointer_cast、static_pointer_cast,但它们需要继承层次结构。
我查看了 reinterpret_pointer_cast,但它在 C++11 中不可用。
我曾尝试使用我的行为接口继承的根接口(类似于 COM 中的 IUnknown 或 Delphi 中的 IInterface),创建继承层次结构,但后来我 运行 陷入菱形问题.
我看到了一些关于将方法添加到基础接口以 return 引用每个行为接口的建议,但这是一种我真的不想要的耦合,因为我可能需要添加其他行为和 class 稍后实施它们的 es。
这是一些我没有编译的代码,显示了我正在尝试做的事情的一个简单示例。
class IBase
{
public:
virtual void DoBaseStuff() = 0;
}
class IBehaviorA
{
public:
virtual void DoBehaviorA() = 0;
}
class IBehaviorB
{
public:
virtual void DoBehaviorB() = 0;
}
class Base : public IBase
{
public:
Base() {}
virtual ~Base() {}
virtual void DoBaseStuff() { /* ... */ }
}
class JustA : public IBase, public IBehaviorA
{
public:
JustA() {}
virtual ~JustA() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorA() { /* ... */ }
}
class JustB : public IBase, public IBehaviorB
{
public:
JustB() {}
virtual ~JustB() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorB() { /* ... */ }
}
class AandB : public IBase, public IBehaviorA, public IBehaviorB
{
public:
AandB() {}
virtual ~AandB() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorA() { /* ... */ }
virtual void DoBehaviorB() { /* ... */ }
}
void ProcessAllBehaviorA(std::vector<std::shared_ptr<IBase>> bases)
{
for (auto& base : bases)
{
std::shared_ptr<IBehaviorA> behaviorA
= SOME_KIND_OF_CAST<IBehaviorA>(base);
if (behaviorA != nullptr)
{
behaviorA->DoBehaviorA();
}
}
}
void main()
{
std::vector<std::shared_ptr<IBase>> bases;
bases.push_back(std::shared_ptr<IBase>(new Base()));
bases.push_back(std::shared_ptr<IBase>(new JustA()));
bases.push_back(std::shared_ptr<IBase>(new JustB()));
bases.push_back(std::shared_ptr<IBase>(new AandB()));
ProcessAllBehaviorA(bases);
}
我想知道在 ProcessAllBehaviorA 方法中 SOME_KIND_OF_CAST 占位符所在的位置要做什么。
我确信我不是第一个尝试这样做的人。
其他人如何在 C++ 中使用智能指针实现接口隔离原则(或类似我的模式)?
I have explored dynamic_pointer_cast, static_pointer_cast but they require an inheritance hierarchy.
您的代码 确实 具有继承层次结构,因此 std::dynamic_pointer_cast
可以正常工作!我已将一些行为添加到您的代码中,它按预期工作。
#include <memory>
#include <vector>
#include <iostream>
class IBase
{
public:
virtual void DoBaseStuff() = 0;
};
class IBehaviorA
{
public:
virtual void DoBehaviorA() = 0;
};
class IBehaviorB
{
public:
virtual void DoBehaviorB() = 0;
};
class Base : public IBase
{
public:
Base() {}
virtual ~Base() {}
virtual void DoBaseStuff() { /* ... */ }
};
class JustA : public IBase, public IBehaviorA
{
public:
JustA() {}
virtual ~JustA() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorA() { std::cout << "I am just A!" << std::endl; }
};
class JustB : public IBase, public IBehaviorB
{
public:
JustB() {}
virtual ~JustB() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorB() { /* ... */ }
};
class AandB : public IBase, public IBehaviorA, public IBehaviorB
{
public:
AandB() {}
virtual ~AandB() {}
virtual void DoBaseStuff() { /* ... */ }
virtual void DoBehaviorA() { std::cout << "I am A and B" << std::endl; }
virtual void DoBehaviorB() { /* ... */ }
};
void ProcessAllBehaviorA(std::vector<std::shared_ptr<IBase>> bases)
{
for (auto& base : bases)
{
std::shared_ptr<IBehaviorA> behaviorA
= std::dynamic_pointer_cast<IBehaviorA>(base);
if (behaviorA != nullptr)
{
behaviorA->DoBehaviorA();
}
else {
std::cout << "Requested pointer does not implement A." << std::endl;
}
}
}
void main()
{
std::vector<std::shared_ptr<IBase>> bases;
bases.push_back(std::shared_ptr<IBase>(new Base()));
bases.push_back(std::shared_ptr<IBase>(new JustA()));
bases.push_back(std::shared_ptr<IBase>(new JustB()));
bases.push_back(std::shared_ptr<IBase>(new AandB()));
ProcessAllBehaviorA(bases);
}
输出:
Requested pointer does not implement A.
I am just A!
Requested pointer does not implement A.
I am A and B
顺便说一下,您在 class 定义的末尾漏掉了分号。