如何解决继承的静态工厂方法返回子类类型
我有一个由 Logging
、LoggingString
等继承的 LoggingInt
类,每个类都有一个 writeLog
函数,该函数接受相应的类型:
class Logging {
public:
explicit Logging(const LoggingConfig& config);
...
}
class LoggingString : public Logging {
public:
using Logging::Logging;
writeLog(std::string str);
...
}
在我使用 LoggingString 的代码中,我希望能够像这样调用工厂函数:
std::unique_ptr<LoggingString> logger = LoggingString::CreateIfLoggingEnabled(LoggingConfig{...});
std::unique_ptr<LoggingInt> logger = LoggingInt::CreateIfLoggingEnabled(LoggingConfig{...});
考虑到它们都使用派生自基类 Logging
的相同构造函数,是否可以将这个 static Logging::CreateIfLoggingEnabled
函数放在基类中并以某种方式使其由 {{1} } 派生类,而是返回一个 Logging
?也许像这样的模板:
unique_ptr<LoggingDerivedClass>
不确定这是否可行,此外必须指定 class Logging {
public:
explicit Logging(const LoggingConfig& config);
template<typename T> static std::unique_ptr<T> CreateIfLoggingEnabled(const LoggingConfig& config) {
...
return std::unique_ptr<T>{};
}
...
}
std::unique_ptr<LoggingString> logger = LoggingString::CreateIfLoggingEnabled<LoggingString>(LoggingConfig{...});
两次似乎是多余的。还有其他选择吗?
解决方法
必须指定 LoggingString
两次似乎是多余的。
您不必指定 LoggingString
两次(如果计算 logger
变量声明,则指定三次)。您可以将 LoggingString::
替换为 Logging::
,并使用 auto
作为变量,例如:
class Logging {
public:
explicit Logging(const LoggingConfig& config);
template<typename T>
static std::unique_ptr<T> CreateIfLoggingEnabled(const LoggingConfig& config) {
...
return std::make_unique<T>(config);
}
...
};
auto logger = Logging::CreateIfLoggingEnabled<LoggingString>(LoggingConfig{...});
auto logger = Logging::CreateIfLoggingEnabled<LoggingInt>(LoggingConfig{...});
或者,您可以使用 CRTP 将派生类型传递给基类,例如:
template<typename Derived>
class Logging {
public:
explicit Logging(const LoggingConfig& config);
static std::unique_ptr<Derived> CreateIfLoggingEnabled(const LoggingConfig& config) {
...
return std::make_unique<Derived>(config);
}
...
};
class LoggingString : public Logging<LoggingString> {
public:
using Logging<LoggingString>::Logging;
void writeLog(std::string str);
...
};
class LoggingInt : public Logging<LoggingInt> {
public:
using Logging<LoggingInt>::Logging;
void writeLog(int i);
...
};
auto logger = LoggingString::CreateIfLoggingEnabled(LoggingConfig{...});
auto logger = LoggingInt::CreateIfLoggingEnabled(LoggingConfig{...});
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。