【问题标题】:C++ Goodpractice for multiple derived class of the same base class同一基类的多个派生类的 C++ 良好实践
【发布时间】:2019-07-02 11:48:47
【问题描述】:

目标:我正在制作一个具有 10 种模式样式的程序,这些样式被实现为派生自一个通用模式基类的不同类。 main.cpp 根据用户选择的样式创建图案样式。

问题:

如果不创建这么多的标题,main 怎么能知道所有的模式样式?

ex :如果分开,这些将是文件。

baseclass.h
baseclass.cpp
derivedclass1.h
derivedclass1.cpp
derivedclass2.h
derivedclass2.cpp
derivedclass3.h
derivedclass3.cpp
derivedclass4.h
derivedclass4.cpp
main.cpp

main.cpp 内:

#include "derivedclass1.h"
#include "derivedclass2.h"
#include "derivedclass3.h"
#include "derivedclass4.h"

这不是太多了吗?

有没有办法只调用 1 个命名空间,其中包含所有派生类的列表,如统一(在单一行为中派生)?我知道它使用 c# 但仍然..

=====想法=====

也许是一个调用同一基类的所有派生类的 foreach 循环?或者我应该创建一个main_header.h 哪个#include 的所有样式并包括来自main.cpp 的样式?

【问题讨论】:

  • 包含单个源文件太多了。不要包含 .cpp !
  • 抱歉,它应该是 .h 文件

标签: c++


【解决方案1】:

包括头文件,而不是 .cpp 文件。

如果出于某种原因您仍需要包含 .cpp 文件:不要(但将其重命名为 _impl.h 等用于模板)

改为包含头文件

#include "derivedclass1.h"
#include "derivedclass2.h"
#include "derivedclass3.h"
#include "derivedclass4.h"

如果这看起来太过分了:将相似的类放在同一个文件中并不是一种罪过(尽管这应该是一种罕见的情况):

然后包括:

#include "allderivedclasses.h"

【讨论】:

  • 很抱歉它应该是.h文件
【解决方案2】:

您的主要关注点似乎是“main 如何知道所有模式样式?”。 答案是工厂函数采用模式样式名称(可能还有一些参数)并生成正确的模式样式对象。每个模式样式实现都负责将自己注册到工厂,这样main 就可以保持无视。

有关此技术的更详细说明,请参阅https://dev.to/fenbf/factory-with-self-registering-types--35h1

在下面的代码中,PatternStyle 类公开了两个静态函数:

  • register_pattern:每个子类都可以在启动时将其名称和静态构造函数注册到std::map pattern_styles
  • create:在std::map 中查找名称并调用构造函数(如果有)。

pattern_style.h

class PatternStyle {
...
public:
using Constructor = std::function<std::unique_ptr<PatternStyle>()>;
static std::unique_ptr<PatternStyle> create(const std::string& name);
static bool register_pattern(const std::string& name, Constructor ctor);
};

pattern_style.cpp

static std::map<std::string, PatternStyle::Constructor> pattern_styles;

std::unique_ptr<PatternStyle> PatternStyle::create(const std::string& name) {
    auto it = pattern_styles.find(name);
    if (it == pattern_styles.cend())
        return {};
    else
        return it->second();
}

bool PatternStyle::register_pattern(const std::string& name, Constructor ctor) {
    pattern_styles[name] = ctor;
    return true;
}

这允许子类像这样注册自己:

wavy_pattern_style.h

class WavyPatternStyle : public PatternStyle {};

wavy_pattern_style.cpp

static bool registration = PatternStyle::register_pattern("wavy", std::make_unique<WavyPatternStyle>);

注意:make_unique 的这种使用需要 C++14。如果您只有 C++11,则需要制作专用的构造函数(或使用 lambda)。

使用此构造,只需在单独的文件中定义模式样式并将它们包含在您的构建系统中,这将解决您的次要问题。

【讨论】:

  • 我已阅读您的回复.. 更新了问题,并会在我尝试后回复... 这实际上是我一直在寻找的
猜你喜欢
  • 1970-01-01
  • 2013-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多