c – 在不更改接口的情况下向对象添加功能
发布时间:2020-12-16 03:32:50 所属栏目:百科 来源:网络整理
导读:我有一个对象作为接口的引用/指针.如果存在该方法,我想在具体对象上调用一个方法,而不需要更改接口,破坏封装或编写任何可怕的黑客攻击.怎么做到呢? 这是一个例子. 我有一个界面: class IChatty{public: virtual ~IChatty() {}; virtual std::string Speak(
我有一个对象作为接口的引用/指针.如果存在该方法,我想在具体对象上调用一个方法,而不需要更改接口,破坏封装或编写任何可怕的黑客攻击.怎么做到呢?
这是一个例子. 我有一个界面: class IChatty { public: virtual ~IChatty() {}; virtual std::string Speak() const = 0; }; 并且这个界面的多个具体实现: class SimpleChatty : public IChatty { public: ~SimpleChatty() {}; virtual std::string Speak() const override { return "hello"; } }; class SuperChatty : public IChatty { public: void AddToDictionary(const std::string& word) { words_.insert(word); } virtual std::string Speak() const override { std::string ret; for(auto w = words_.begin(); w != words_.end(); ++w ) { ret += *w; ret += " "; } return ret; } private: std::set<std::string> words_; }; SuperChatty :: AddToDictionary方法不存在于抽象的IChatty接口中,尽管它可以包含在另一个新接口中. 在现实世界中,这些对象是通过工厂构建的,它们本身是抽象接口的具体实例.然而,就我们的目的而言,这与手头的问题是正交的: int main() { IChatty* chatty = new SuperChatty; chatty->AddToDictionary("foo"); std::cout << chatty->Speak() << std::endl; } 由于AddToDictionary不是IChatty接口的一部分(并且不能成为其中的一部分),我可以称之为. 如何在不破坏封装,写一些可怕的黑客或采取任何其他设计快捷方式的情况下在chatty指针上调用AddToDictionary? 注意:在现实世界中,字典是SuperChatty对象本身的一部分,不能与它分开. 注2:我不想向下倾斜到具体类型. 解决方法
将字典作为SuperChatty可以更新和引用的对象:
class Dictionary { public: void add(const std::string& word); const std::set<std::string>>& words() const; //.. }; class SuperChatty : public IChatty { public: SuperChatty(Dictionary& dictionary) : dictionary(dictionary) { } virtual std::string Speak() const override { auto words = dictionary.words(); ostringstream oss; copy(words.begin(),words.end(),ostream_iterator<string>(oss," ")); return oss.str(); } }; 用法: int main() { Dictionary dictionary; IChatty* chatty = new SuperChatty(dictionary); dictionary.add("foo"); std::cout << chatty->Speak() << std::endl; } 编辑 好的,问题改变了. 如果你正确地做到这一点,你需要将自己与糟糕的底层系统隔离开来: struct Dictionary { virtual ~Dictionary () {} virtual void add(const std::string& word) = 0; }; struct Instrumenter { virtual ~Instrumenter () {} virtual void addDictionary(Dictionary& dictionary) = 0; }; struct Chatter { virtual ~Chatter() {} virtual string speak() const = 0; virtual void instrument(Instrumenter& instrumenter) = 0; }; 这些实现如下: class BasicChatter : public Chatter { virtual string speak() const { return chatty.Speak(); } virtual void instrument(Instrumenter& instrumenter) { // do nothing } private: SimpleChatty chatty; }; class SuperChatter : public Chatter { SuperChatter () : dictionary(chatty); virtual void instrument(Instrumenter& instrumenter) { instrumenter.addDictionary(dictionary); } virtual string speak() const { return chatty.Speak(); } private: SuperChatty chatty; DictionaryImpl dictionary; }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |