此工厂功能有什么问题?
What is the issue with this factory function?
在下面的代码中,我编写了一个工厂方法来创建类继承中的类型对象。
#include <iostream>
#include <memory>
using namespace std;
enum Type {
_Base, _A, _B, _C
};
class Base{
private:
Type type = _Base;
public:
virtual Type getType(){
return type;
}};
class A : public Base{
private:
Type type = _A;
public:
using Base::Base;
};
class B : public Base{
private:
Type type = _B;
public:
using Base::Base;
};
class C : public Base{
private:
Type type = _C;
public:
using Base::Base;
};
shared_ptr<Base> letterFactory(Type which){
shared_ptr<Base> base = make_unique<Base>(Base());
switch (which){
case _A:
base = make_unique<Base>(A());
case _B:
base = make_unique<Base>(A());
case _C:
base = make_unique<Base>(C());
}
return base;
}
int main(){
shared_ptr<Base> instanceOfA = letterFactory(_A);
cout << instanceOfA->getType() << endl;
shared_ptr<Base> instanceOfB = letterFactory(_B);
cout << instanceOfB->getType() << endl;
shared_ptr<Base> instanceOfC = letterFactory(_C);
cout << instanceOfC->getType() << endl;
return 0;
};
输出为
0
0
0
如何进行输出
1
2
3
你的工厂有点缺陷,你的getType()
函数在派生类中没有被重写。我猜你想做一些类似的事情:
#include <iostream>
#include <memory>
using namespace std;
enum Type {
_Base, _A, _B, _C
};
class Base{
public:
virtual ~Base() = default;
virtual Type getType() const {
return _Base;
};
};
class A : public Base{
public:
virtual Type getType() const override {
return _A;
};
};
class B : public Base{
public:
virtual Type getType() const override {
return _B;
};
};
class C : public Base{
public:
virtual Type getType() const override {
return _C;
};
};
unique_ptr<Base> letterFactory(Type which){
switch (which){
case _Base:
return make_unique<Base>();
case _A:
return make_unique<A>();
case _B:
return make_unique<B>();
case _C:
return make_unique<C>();
}
return nullptr;
}
int main(){
shared_ptr<Base> instanceOfA = letterFactory(_A);
cout << instanceOfA->getType() << endl;
shared_ptr<Base> instanceOfB = letterFactory(_B);
cout << instanceOfB->getType() << endl;
shared_ptr<Base> instanceOfC = letterFactory(_C);
cout << instanceOfC->getType() << endl;
return 0;
};
请注意,我们完全删除了type
成员,而是正确覆盖了getType()
函数。此外,像这样的工厂函数通常会返回unique_ptr
(如果您真的愿意,可以隐式转换为shared_ptr
(。
您的Base
类有一个成员type
和一个返回成员type
值的虚拟成员函数getType()
。您的类A
、B
和C
派生自Base
。这意味着它们都有一个Base
子对象。该子对象包含成员Base::type
。此外,它们还添加了另一个成员type
,然后从未被任何东西使用过。此外,它们都不会覆盖getType
方法。所以每当你打电话
instanceOfX->getType()
即使instanceOfX
指向其中一个派生类的实例,由于没有一个派生类覆盖getType
,你最终会调用Base::getType
,这将返回Base::type
的值,它总是_Base
...
你真正想要的可能是类似的东西:
struct Base
{
virtual Type getType() const = 0;
protected:
Base() = default;
Base(Base&&) = default;
Base(const Base&) = default;
Base& operator =(Base&&) = default;
Base& operator =(const Base&) = default;
~Base() = default;
};
class A : public Base
{
public:
Type getType() const override { return _A; }
};
class B : public Base
{
public:
Type getType() const override { return _B; }
};
class C : public Base
{
public:
Type getType() const override { return _C; }
};
请注意,这几乎可以肯定是糟糕的设计。这种getType
方法的唯一用途是,客户端代码可以找出它所获得的Base*
指向的对象的具体类型。如果您需要此信息,您的设计违反了利斯科夫替换原则......
除此之外,请注意_Base
、_A
、_B
和_C
是保留名称 [lex.name]/3,您不应该在C++代码中使用...
我稍微重构了一下您的代码,只是为了应用一些最佳实践:
- 使用
enum class
而不是原始enum
因为enum class
表示作用域枚举类型,并且它也是强类型的,这意味着您无法轻松地将其转换为整数作为原始enum
(这就是我们有to_integral
模板函数的原因( - 不希望使用
using namespace std;
,因为它将整个 std 命名空间导入到程序的当前命名空间中 - 另外,我认为您想使用
std::make_shared
而不是std::make_unique
#include <memory>
#include <iostream>
enum class Type : int {
_Base = 0,
_A = 1,
_B = 2,
_C = 3
};
class Base{
private:
Type type = Type::_Base;
public:
virtual Type getType(){
return type;
}
};
class A : public Base{
private:
Type type = Type::_A;
public:
virtual Type getType() override {
return type;
}
};
class B : public Base{
private:
Type type = Type::_B;
public:
virtual Type getType() override {
return type;
}
};
class C : public Base{
private:
Type type = Type::_C;
public:
virtual Type getType() override {
return type;
}
};
std::shared_ptr<Base> letterFactory(Type which){
switch (which){
case Type::_A:
return std::make_shared<A>();
case Type::_B:
return std::make_shared<B>();
case Type::_C:
return std::make_shared<C>();
default:
return std::make_shared<Base>(Base());
}
}
template <typename Enum>
constexpr typename std::enable_if<std::is_enum<Enum>::value,
typename std::underlying_type<Enum>::type>::type
to_integral(Enum const& value) {
return static_cast<typename std::underlying_type<Enum>::type>(value);
}
int main(){
std::shared_ptr<Base> instanceOfA = letterFactory(Type::_A);
std::cout << to_integral(instanceOfA->getType()) << std::endl;
std::shared_ptr<Base> instanceOfB = letterFactory(Type::_B);
std::cout << to_integral(instanceOfB->getType()) << std::endl;
std::shared_ptr<Base> instanceOfC = letterFactory(Type::_C);
std::cout << to_integral(instanceOfC->getType()) << std::endl;
return 0;
};
现场示例
相关文章:
- 警告处理为错误这里有什么问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 当我尝试添加 2 个大字符串时,我无法弄清楚出了什么问题
- 违反const正确性:我应该现实地期待什么问题
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- 我的逻辑反转字符串中的元音有什么问题?
- 需要以下代码的帮助,下面的代码有什么问题
- 常量公共成员有什么问题?
- c++无值sort()的问题是什么?
- 以下代码中的函数模板有什么问题?
- 这个返回元素位置的基于循环的函数有什么问题?
- creat_list2功能有什么问题?
- 基本的 c++ 问题:如果我在函数中创建某些内容并返回它会发生什么?
- 我遇到了黑客排名中的问题"TWO STRINGS"的三个测试用例的分段错误。原因是什么?
- 什么是钻石问题?是一系列问题还是特定问题?
- 格式说明符C++有什么问题
- 我应该在 main 函数中写什么来测试我的问题?
- 任何人都可以告诉我我的 C++ 代码出了什么问题?
- 方法问题 - 什么会改变值,什么不会改变?什么是无效的?