c++ - 此工厂功能有什么问题?

标签 c++ oop design-patterns

在下面的代码中,我编写了一个工厂方法来创建类heirachy中的类型的对象。


#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

最佳答案

您的Base类具有一个成员type和一个虚拟成员函数getType(),该函数返回成员type的值。您的类ABC源自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*指向的对象的具体类型。如果您需要此信息,则您的设计违反了Liskov Substitution principle

除此之外,请注意_Base_A_B_C是保留名称[lex.name]/3,您不应该在C++代码中使用…

关于c++ - 此工厂功能有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59662257/

相关文章:

c# - 在这种情况下我应该使用接口(interface)还是抽象类?

javascript - 使用显示模式将 ES6 类属性设为私有(private)

java - 当 "if else"/"instance of"是不可避免的时候,除了使用访问者模式,我们如何改进设计呢?

design-patterns - 命令模式与访问者模式

c++ - 如何读取 .avi 文件 C++

c++ - 指针和 "NULL"

c++ - 在类层次结构中初始化变量

c++ - 编写编译器 : how to get simple templates to work?

c++ - 菜鸟的快速 g++ 错误诊断

java - 在 Java 中恢复旧对象状态