C++ 扩展类
编辑回答:虽然我最初的问题没有像康拉德·鲁道夫提供的答案那样准确地解释我的需求,但他(出于偶然或设计)基本上为我写了我想写的东西!该类本身并没有得到扩展,而是通过使该类意识到允许它(该类)处理更广泛问题的新函数来扩展其功能。我非常感谢你给出了一个很好的答案,这也是一个很好的教程,即使它确实需要一些ahemm灯光?读我的书;-) 我确信这是一个非常基本的问题,但我正在尝试自学C++,我用的参考书提供的答案我不懂。 对于我的项目,我定义了一个C++ 扩展类,c++,inheritance,extend,C++,Inheritance,Extend,编辑回答:虽然我最初的问题没有像康拉德·鲁道夫提供的答案那样准确地解释我的需求,但他(出于偶然或设计)基本上为我写了我想写的东西!该类本身并没有得到扩展,而是通过使该类意识到允许它(该类)处理更广泛问题的新函数来扩展其功能。我非常感谢你给出了一个很好的答案,这也是一个很好的教程,即使它确实需要一些ahemm灯光?读我的书;-) 我确信这是一个非常基本的问题,但我正在尝试自学C++,我用的参考书提供的答案我不懂。 对于我的项目,我定义了一个类错误处理程序{},它处理来自程序各个点的异常消息和错误号
类错误处理程序{}
,它处理来自程序各个点的异常消息和错误号。它会将错误记录到文件中,并/或使用各种成员功能将消息打印到屏幕上
我的目标是创建它,使它拥有自己的.h和.cpp文件,如果以后需要扩展它,只需添加一个新的成员函数来处理一些更模糊的错误操作
那么,我的问题是:
因为在error.h
中,我有代码:
class error_handler
{
// ctor dtor copy logger screen functions defined
}
在error\u handler.cpp
中,我完成了这些定义
如何简单地向类添加新函数?我不想把它分类,只是简单地扩展它
对于一个用例场景,假设error_handler是一个在专有包中定义的类,我不能自由地直接修改源代码,但可以在单独的代码中扩展它
编辑:到目前为止,答案和评论似乎表明我正在尝试做一些语言不应该做的事情。如果是这样,那就这样吧,我在这里学到了一些东西。希望不是这样的话,我会把问题放在一点,看看还有什么会在这篇文章中徘徊…… < p>在C++中,你不能修改一个类而不修改<代码>类< /Cuth>块,并添加你的函数定义(即在<代码>错误.H./COD>)
如果无法修改头文件,那么您唯一的选择就是继承类,或者编写在类上运行的非成员函数(但这些函数只能看到公共成员)扩展类而不修改其原始定义的唯一方法是创建从该类派生的新类。也许你应该更具体地说明你想做什么。使用
错误处理程序的现有代码是否必须受到您的更改的影响?例如,如果您只想添加一个以不同方式记录错误的函数,并且只想在新代码中使用该函数,则可以创建一个普通的非成员函数,该函数接受引用error\u handler
,但更简洁的方法是创建my\u error\u handler
(派生)使用新方法初始化。如果希望将my\u error\u handler
实例的指针/引用传递给现有代码,则可以将其自由转换为error\u handler
的指针/引用。这在很大程度上取决于这些函数是什么。对于您的应用程序,我将继续并假设您要添加的函数用于处理其他错误类型
为了简单起见,我们假设每个函数(我们称之为handle
)只传递了一个错误对象,它分析并处理或不处理该对象。它返回一个bool
来表示这一点
然后您可以拥有以下(简化的)错误处理程序
类:
class error_handler {
public:
using handler_t = bool (*)(error const&);
std::vector<handler_t> handlers;
// …
void add_handler(handler_t handler) {
handlers.push_back(handler);
}
void handle_error(error const& error) {
for (auto const& handler : handlers)
if (handler(error))
break;
}
};
扩展类的通常(本质上是唯一的)方法是将其“子类”化(即从中派生)。“我不想把它分类,只是简单地扩展它。”听起来有点像“我想游泳而不被淋湿。”@JerryCoffin嗯,在一些(相当成熟和专业的)项目中使用了一些肮脏的宏黑客。然而,除非您真正知道自己在做什么,否则您可能应该使用派生/继承机制,尤其是在入门级。@NeonGlow我至少可以想出三种没有继承的方法。事实上,我最喜欢的选择可能不是遗产。@Jerry Coffin--LOL。。。不害怕被淋湿,只是询问“可能吗”。我涉足过的其他语言都有一个类定义的extends
修饰符。我希望这里也有类似的东西。@luk32——正如你所说,我绝对是入门级的。所以宏黑客仍然在我的未来。。。这就是我害怕的。解释了为什么没有一本书引用这个概念。@Jase:这也有道理。如果您可以任意地从不同的翻译单元重新编写类型,您将能够造成各种各样的破坏@LightnessRacesinOrbit——哈哈——是的,会的!我同意(我的松散理解)不可能的原因。这会产生各种各样的问题。但知识就是力量,我在寻求理解语言,而不是强迫它进入新的、模糊的形状和方向。谢谢你再次向我指出这一点。这在书中提到过,但我到目前为止还没有建立联系。@LightnessRacesinOrbit,这被称为monkey patching,在其他语言中是一个常见的概念。@Konrad:这只是我不使用这些语言的一个原因的例子。:)还不确定如何转换指针/引用。我(也许是愚蠢地)在书中跳来跳去,试图重写非常旧的代码,作为学习新概念的一种方式。(原始代码是C=64基本)哇!!这是一个比我想象的要多得多的例子!您添加了一些我不熟悉的功能,因此我正在进行更多阅读。(特别是使用handler\u t=bool(*)(error const&)
我还没有看到在那种上下文中使用)感谢您提供了非常详细的示例!C++11的新手
// Simple logging “handler”. Needs to be added first!
extern error_handler global_error_handler;
bool log_handler(error const& error) {
std::cerr << error.message() << '\n';
return false; // We only log, we don’t handle.
}
global_error_handler.add_handler(log_handler);
// Handler for missing dog food
extern error_handler global_error_handler;
errno_t const MISSING_DOG_FOOD = 42;
bool dog_food_missing(error const& error) {
if (error.code() != MISSING_DOG_FOOD)
return false;
global_dog_food_container.add(some_food());
return true;
}
global_error_handler.add_handler(dog_food_missing);